修改了生产者/消费者的例子,有什么问题吗?

时间:2011-04-30 14:57:45

标签: c#

我修改了生产者/消费者示例http://msdn.microsoft.com/en-us/library/yy12yx1f(v=vs.80).aspx。我不希望Consumer在事件上处理queue“。相反,我使用无限循环(与生产者中使用的相同)并尝试尽快处理所有元素。这种方法有问题吗?如果我们可以使用无限循环,为什么我们需要Consumer和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 个答案:

答案 0 :(得分:1)

我看到你所拥有的两个潜在问题

  1. 当队列为空时,你的版本将处于一个繁忙的循环中,烧掉宝贵的CPU,使用一个事件让线程进入睡眠状态,直到有实际的工作要做。
  2. 通过锁定队列并像处理一样在单个循环中处理队列中的所有元素,可以消除让多个消费者线程处理队列的潜在好处。现在因为你只是在你的例子中增加了一个计数,这可能看起来不是什么大问题,但如果你开始真正处理你出列的项目,你可以从多线程处理这项工作中受益。
  3. 如果您使用的是.NET 4,您可能需要查看使用BlockingCollection(T) Class,这样可以为所有这些提供更清晰的解决方案,而且启动锁定更少。

答案 1 :(得分:0)

如果您的ExitThreadEvent设置进入竞争状态,可能会出现潜在问题(因为您没有显示代码的这一部分,如果可能发生这种情况很难判断)。

答案 2 :(得分:0)

如果您能够使用.NET 4.0,则可以使用内置的BlockingCollection类来简单有效地解决此问题。