BlockingCollection(Of T)的目的是什么

Iña*_*oro 19 .net parallel-extensions

我试图在.NET 4上新的Parallel Stacks的上下文中理解BlockingCollection的目的.

MSDN文档说:

BlockingCollection用作IProducerConsumerCollection实例的包装器,允许从集合中删除尝试以阻止数据可用于删除.类似地,可以创建BlockingCollection以强制执行IProducerConsumerCollection中允许的数据元素数量的上限; 然后可以阻止对集合的添加尝试,直到空间可用于存储添加的项目.

但是,当我查看一些IProducerConsumerCollection的实现时,比如ConcurrentQueue,我看到它们提供了一个无锁,线程安全的实现.那么为什么需要BlockingCollection提供的锁机制呢?MSDN中的所有示例都显示通过BlockingCollection包装器使用这些集合,直接使用这些集合有哪些麻烦?使用BlockingCollection会产生什么好处?

Thi*_*ilo 18

如果您无需执行任何其他操作(或者更确切地说:在执行操作之前无法继续),则阻止直到可以执行操作是一种方便.

如果从要读取数据的非阻塞队列,并有目前没有数据,你必须定期轮询,或者等待一些信号,直到有数据.如果队列阻塞,那就已经自动完成了.

同样,如果您尝试添加到已满的非阻塞队列,则操作将失败,然后您必须弄清楚要执行的操作.阻塞队列只会等到有空间.

如果您有一些聪明的事情而不是等待(例如检查另一个队列中的数据,或者引发QueueTooFullException),那么您需要非阻塞队列,但通常情况并非如此.

通常,有一种方法可以指定阻塞队列的超时.


Guf*_*ffa 7

锁定的目的是锁定本身.您可以从集合中读取多个线程,如果没有可用数据,则线程将保持锁定状态,直到新数据到达.

此外,通过设置大小限制的功能,您可以让填充集合的生产者线程尽可能多地添加到其中.当集合达到限制时,线程将直接锁定,直到使用者线程为数据腾出空间.

这样,您可以使用该集合来限制数据的吞吐量,而无需自行进行任何检查.您的线程只是可以读取和写入,并且集合负责根据需要保持线程正常工作或休眠.

  • 重要的是"没有自己检查".你的生产者代码和消费者代码都可以非常简单,几乎与你的非并行版本完全相同,如果没有(有用的)为它们做什么,你仍然可以获得线程入睡的好处. (3认同)