在C#中,BlockingCollection類可以很好地實現生產者消費者模式。它是一個線程安全的集合,可以在多個線程之間安全地傳遞數據。以下是一個簡單的示例:
首先,創建一個名為ProducerConsumerExample
的類,并在其中定義兩個方法:Produce
和Consume
,分別用于生產數據和消費數據。
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
class ProducerConsumerExample
{
private static BlockingCollection<int> _blockingCollection = new BlockingCollection<int>();
static void Main(string[] args)
{
// 創建兩個任務,一個用于生產數據,另一個用于消費數據
Task producerTask = Task.Run(() => Produce());
Task consumerTask = Task.Run(() => Consume());
// 等待兩個任務完成
Task.WaitAll(producerTask, consumerTask);
}
static void Produce()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"Producing: {i}");
_blockingCollection.Add(i);
Thread.Sleep(1000); // 模擬生產過程耗時
}
// 生產完成后,通知消費者任務已完成
Console.WriteLine("All items produced.");
_blockingCollection.CompleteAdding();
}
static void Consume()
{
foreach (var item in _blockingCollection.GetConsumingEnumerable())
{
Console.WriteLine($"Consuming: {item}");
Thread.Sleep(2000); // 模擬消費過程耗時
}
Console.WriteLine("All items consumed.");
}
}
在這個示例中,我們使用了一個名為_blockingCollection
的BlockingCollection<int>
實例來存儲數據。Produce
方法用于生產數據,將數據添加到BlockingCollection
中。Consume
方法用于消費數據,從BlockingCollection
中獲取數據并處理。
BlockingCollection
提供了CompleteAdding
方法,當生產完成后調用此方法,可以通知消費者任務已完成。GetConsumingEnumerable
方法返回一個可枚舉的序列,該序列會在BlockingCollection
中有新元素時自動更新。這樣,消費者可以在有新數據時立即開始處理,而不需要不斷檢查是否有新數據。
在Main
方法中,我們創建了兩個任務,一個用于生產數據,另一個用于消費數據,并使用Task.WaitAll
等待它們完成。