Модифицированный пример производителя / потребителя, есть какие-то проблемы с ним? - PullRequest
1 голос
/ 30 апреля 2011

Я изменил пример Производитель / Потребитель http://msdn.microsoft.com/en-us/library/yy12yx1f(v=vs.80).aspx. Я не хочу, чтобы Consumer обрабатывал queue "по событию". Вместо этого я использую бесконечный цикл (такой же, как в Producer) и пытаюсь обработать все элементы как можно скорее. Есть ли проблемы с таким подходом? Зачем нам нужны «события» между Потребителем и Производителем, если мы можем использовать бесконечный цикл?

    // Consumer.ThreadRun
    public void ThreadRun()
    {
        int count = 0;
        while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
        {
            lock (((ICollection)_queue).SyncRoot)
            {
                while (_queue.Count > 0)
                {
                    int item = _queue.Dequeue();
                    count++;
                }
            }
        }
        Console.WriteLine("Consumer Thread: consumed {0} items", count);
    }

Ответы [ 3 ]

1 голос
/ 30 апреля 2011

Я вижу две потенциальные проблемы с тем, что у вас есть

  1. Когда очередь пуста, ваша версия будет находиться в занятом цикле, сжигающем драгоценный ЦП, используя событие переводит поток в спящий режим до тех пор, пока не будет фактически выполнена работа.
  2. Блокируя очередь и обрабатывая все элементы в очереди в одном цикле, как вы делаете, вы сводите на нет потенциальные выгоды от обработки потоков несколькими потребителями. Теперь, поскольку вы только увеличиваете счетчик в своем примере, это может показаться не таким уж большим делом, но если вы начнете выполнять реальную работу с объектами, которые вы удаляете, вы можете извлечь выгоду из того, что несколько потоков будут обрабатывать эту работу.

Если вы используете .NET 4, возможно, вы захотите взглянуть на использование BlockingCollection (T) Class , которое дало бы еще более чистое решение для всего этого с меньшим количеством блокировок для загрузки.

0 голосов
/ 30 апреля 2011

Если вы можете использовать .NET 4.0, вы можете использовать встроенный класс BlockingCollection для простого и эффективного решения этой проблемы.

0 голосов
/ 30 апреля 2011

Потенциальная проблема может возникнуть, если ваш параметр ExitThreadEvent попадет в состояние гонки (поскольку вы не показываете эту часть кода, трудно сказать, может ли это произойти).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...