gpt4 book ai didi

c# - 生产者/消费者 msdn 示例如何工作?

转载 作者:太空宇宙 更新时间:2023-11-03 11:37:18 24 4
gpt4 key购买 nike

我不明白这个例子是如何工作的http://msdn.microsoft.com/en-us/library/yy12yx1f(v=vs.80).aspx

据我了解,消费者不会读取生产者生成的所有元素。可能我没有正确理解 AutoResetEvent 的工作原理。 Set AutoreResetEvent 几次有意义吗?

    _newItemEvent = new AutoResetEvent(false);
_newItemEvent.Set();
_newItemEvent.Set();
_newItemEvent.Set();
_newItemEvent.Set();

这是我理解的示例:

制作人:

        lock (((ICollection)_queue).SyncRoot)
{
while (_queue.Count < 20)
{
_queue.Enqueue(r.Next(0,100));
_syncEvents.NewItemEvent.Set();
count++;
}
}

消费者:

    while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
{
lock (((ICollection)_queue).SyncRoot)
{
int item = _queue.Dequeue();
}
count++;
}
  1. 生产者锁_queue:

           lock (((ICollection)_queue).SyncRoot)
  2. Producer 添加 1 个元素到 _queue 并设置 NewItemEvent:

            _queue.Enqueue(r.Next(0,100));
    _syncEvents.NewItemEvent.Set();
  3. 消费者进入“while”循环,因为它收到了 NewItemEvent 已设置的通知,NetItemEvent 现在未设置,因为它是 AutoResetEvent:

           while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
  4. 消费者“卡住”在下一行等待 _queue 锁被释放:

           lock (((ICollection)_queue).SyncRoot)
  5. 生产者继续向 _quere 添加 19 个元素并释放 _queue 对象

  6. 消费者获得对_queue对象的锁定并且Dequeue一个元素:

        lock (((ICollection)_queue).SyncRoot)
    {
    int item = _queue.Dequeue();
    }
  7. Consumer 执行“while”循环的第二次迭代,因为 NewItemEvent 已设置,NetItemEvent 现在未设置,因为它是 AutoResetEvent:

  8. 2 次迭代后,Consumer 等待设置 NewItemEvent。

结果:生产者生产了 20 个元素。消费者:Dequeue 只有 2 个元素。

我希望 Consumer Dequeue 所有 20 个元素。

根据一个例子,Consumer 是 Dequeue 20 个元素,问题是我对程序的理解是如何、为什么和什么错误。

最佳答案

您在 MSDN 页面上遗漏了示例的一个重要部分,这是生产者线程中围绕主循环的另一个循环。示例中生产者的工作是尝试在队列中保留至少 20 个项目。

每当它添加一个项目时,消费者都会收到信号,这会导致它删除一个项目,因此队列中的项目少于 20 个。这发生在生产者线程的内部循环内部还是外部并不重要。下次到达 while (_queue.Count < 20) 时这将是错误的,因此生产者将至少再添加一项到队列中,并向消费者发出信号。

无可否认,在我看来,这至少像是一个有些做作的例子,因为消费者不一定会消费队列中的所有条目,但只要生产者继续生产它们,它就会继续消费。

关于c# - 生产者/消费者 msdn 示例如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5841705/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com