多線程操作集合時,ConcurrentQueue
是我常用的,一直用得也挺爽,突然發現了 BlockingCollection
,原來還可以更簡單。。。
BlockingCollection<T>
是一個自帶阻塞功能的線程安全集合類,和 ConcurrentQueue<T>
有點像,不同的是,BlockingCollection<T>
自帶阻塞功能。
Add
方法用於向集合添加元素。Take
方法用於從集合中獲取元素。當集合為空時,Take
方法將阻塞,直到獲取到新元素。CompleteAdding
方法標記集合為完成狀態,此后不能再向集合中添加元素,調用Add
將拋出System.InvalidOperationException
異常。- 調用
CompleteAdding
方法將使阻塞狀態的Take
方法拋出System.InvalidOperationException
異常。 - 實例化
BlockingCollection<T>
時,可以傳入boundedCapacity
參數,設置集合的上限,集合中元素到達上限后,Add
方法將阻塞。 TryAdd
方法在集合滿時,不會阻塞,而是直接返回false
,並且丟棄要插入的元素。TryTake
方法在集合為空時不會阻塞,而是會返回false
。- 當有多個線程
Take
時,將形成一個 Take 隊列,依次獲取到元素。
這是 MSDN 上的 例子:
https://docs.microsoft.com/zh-cn/dotnet/standard/collections/thread-safe/blockingcollection-overview
BlockingCollection<Data> dataItems = new BlockingCollection<Data>(100);
Task.Run(() =>
{
while (!dataItems.IsCompleted)
{
Data data = null;
try
{
data = dataItems.Take();
}
catch (InvalidOperationException) { }
if (data != null)
{
Process(data);
}
}
Console.WriteLine("\r\nNo more items to take.");
});