多線程操作集合時,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.");
});
