在不消耗的情况下观察 BlockingCollection 中的变化
Observing changes in a BlockingCollection without consuming
一个消费者线程和多个生产者线程通过 System.Collections.Concurrent.BlockingCollection<T>
同步它们的工作。
生产者呼吁blockingCollection.Add()
消费者运行
foreach (var item in blockingCollection.GetConsumingEnumerable()) {...}
现在一个生产者想要 "flush" 缓冲区:生产者想要等到所有当前项目都被消耗完。其他生产者可能同时添加更多项目,但该生产者只对当前队列中的项目感兴趣。
如何在不使用忙等待的情况下让生产者等待?
本质上我希望一些非消费者线程在使用 BlockingCollection 的项目时得到通知。
我可以在消费者中设置一个 AutoResetEvent,但这只会唤醒一个等待更改的线程,而可能有多个:
foreach (var item in blockingCollection.GetConsumingEnumerable())
{
myAutoResetEvent.Set()
}
我还可以设置一个 ManualResetEvent:
foreach (var item in blockingCollection.GetConsumingEnumerable())
{
myManualResetEvent.Set()
}
这将唤醒所有等待的线程,但我如何将其再次关闭?
以防你最终使用我的评论
在唤醒生产者的集合中放置一个虚拟项目[=10=]
一个消费者线程和多个生产者线程通过 System.Collections.Concurrent.BlockingCollection<T>
同步它们的工作。
生产者呼吁blockingCollection.Add()
消费者运行
foreach (var item in blockingCollection.GetConsumingEnumerable()) {...}
现在一个生产者想要 "flush" 缓冲区:生产者想要等到所有当前项目都被消耗完。其他生产者可能同时添加更多项目,但该生产者只对当前队列中的项目感兴趣。
如何在不使用忙等待的情况下让生产者等待?
本质上我希望一些非消费者线程在使用 BlockingCollection 的项目时得到通知。
我可以在消费者中设置一个 AutoResetEvent,但这只会唤醒一个等待更改的线程,而可能有多个:
foreach (var item in blockingCollection.GetConsumingEnumerable())
{
myAutoResetEvent.Set()
}
我还可以设置一个 ManualResetEvent:
foreach (var item in blockingCollection.GetConsumingEnumerable())
{
myManualResetEvent.Set()
}
这将唤醒所有等待的线程,但我如何将其再次关闭?
以防你最终使用我的评论
在唤醒生产者的集合中放置一个虚拟项目[=10=]