如果你想玩轉C# 裡面多執行緒,工廠模式,生產者/消費者,佇列等高階操作,就可以和我一起探索這個強大的執行緒安全提供阻塞和限制功能的C#神器類
微軟介紹地址:https://learn.microsoft.com/zh-cn/dotnet/standard/collections/thread-safe/blockingcollection-overview
BlockingCollection 是一個執行緒安全集合類,可提供以下功能:
BlockingCollection
blockingCollection = new(1);
- new 操作符裡面的數位是實現了可選最大容量,超出就執行緒阻塞了,程式一直卡在哪裡
BlockingCollection<int> blockingCollection = new(1);
blockingCollection.Add(1);
blockingCollection.Add(2);
說明:因為限制佇列只能插入一條,第一條沒有消費掉,所以一直卡在插入第二條程式不會往下繼續執行實現了集合為空或已滿時通過插入和移除操作進行阻塞
Task 表面上是Thread但卻是對ThreadPool的封裝,控制和擴充套件性很強,對執行緒的延續,阻塞,取消,超時,比傳統的Thread和ThreadPool強
佇列(Queue)代表了一個先進先出的物件集合。當您需要對各項進行先進先出的存取時,則使用佇列。當您在列表中新增一項,稱為入隊,當您從列表中移除一項時,稱為出隊
建議程式碼還是要動手實現一下,不然體會不到一邊生產資料,同時還能取資料的神仙操作
int count = 0 ;
BlockingCollection<string> blockingCollection = new(1);
//生產者
Task.Factory.StartNew(() =>
{
while (true)
{
blockingCollection.Add("String: " + count);
count++;
if (count > 10)
{
blockingCollection.CompleteAdding();
}
}
});
//消費者
Task.Factory.StartNew(() =>
{
foreach (var element in blockingCollection.GetConsumingEnumerable())
{
Thread.Sleep(1000);
("Work: " + element).Dump();//Dump 為工具Linq的功能
}
});
上面的程式碼中這個方法
GetConsumingEnumerable
很重要,它可以在BlockingCollection集合有資料的時候取資料,沒有的話停止取,可以達到監測的效果
這個案例實現瞭如下功能:
Work: String: 0
Work: String: 1
Work: String: 2
Work: String: 3
Work: String: 4
Work: String: 5
Work: String: 6
Work: String: 7
Work: String: 8
Work: String: 9
Work: String: 10
//先進先出(FIFO)
BlockingCollection<int> bc = new(new ConcurrentQueue<int>());
bc.Add(1);
bc.Add(2);
bc.CompleteAdding();
//先進後出(LIFO)
BlockingCollection<int> bc2 = new(new ConcurrentStack<int>());
bc2.Add(1);
bc2.Add(2);
bc2.CompleteAdding();
bc.Take().Dump("bc1:");
bc2.Take().Dump("bc2:");
bc :1
bc2: 2
這個簡單的案例是想介紹一下其實:BlockingCollection也可以實現佇列的功能
原文地址:https://blog.baibaomen.com/c神器blockingcollection類實現c神仙操作/