BlockingCollection
仅包含添加单个项的方法。如果我想添加集合怎么办?我应该只使用foreach
循环吗?
为什么BlockingCollection
不包含添加集合的方法?我认为这种方法非常有用。
ICollection
接口和许多BCL列表类型的类由于某种原因没有AddRange
方法,这很烦人。
是的,您需要在集合上foreach
,如果您经常使用它,您可以编写自己的扩展方法。
BlockingCollection<T>
是实现IProducerConsumerCollection<T>
接口的底层集合的包装器,默认情况下是ConcurrentQueue<T>
。此接口只有用于添加元素的方法TryAdd
。它没有TryAddRange
。我想,原因是,并不是所有的原生IProducerConsumerCollection<T>
实现都配备了AddRange
功能。ConcurrentStack<T>
确实有PushRange
方法,但ConcurrentQueue<T>
没有等效的方法。
我的理解是,如果这个API存在,它将具有原子语义。这不仅仅是一种方便的方法,可以减少执行多个非原子插入所需的代码。引用ConcurrentStack<T>.PushRange
文件:
当向堆栈添加多个项目时,使用
PushRange
比每次使用Push
一个项目更有效。此外,PushRange保证所有元素都将以原子方式添加,这意味着没有其他线程能够在被推送的元素之间注入元素。items
数组中处于较低索引的项目将被推送到处于较高索引的项目之前。
在阻塞堆栈中添加时,原子性尤其重要,因为添加的项可以立即被当前被阻塞的另一个线程占用。如果我将项目A、B和C按C-B-A的顺序添加,那是因为我希望A放在堆栈的顶部,并首先由另一个线程拾取。但是,由于添加不是原子的,在当前线程设法添加B和A之前,另一个线程可能会赢得比赛并获得C。根据我的实验,这种情况很少发生,但没有办法阻止。如果绝对需要强制执行插入顺序,那么除了从头开始实现自定义BlockingStack<T>
集合之外,别无选择。