解決此問題的最佳方法是使用包裝在BlockingCollection<T>
中的ConcurrentQueue<T>
。使用這個結果對象並從任何地方向它排列值。然後創建5個循環中運行處理方法的任務。每次線程完成一個項目的處理時,它都會嘗試從集合中取出另一個項目。如果隊列爲空,則會阻塞,直到添加新值,或在BlockingCollection上調用AddingComplete()。
// create a blocking collection
// the constructor will take an IProducerConsumerCollection
// or it will use a ConcurrentQueue<T> by default if none is provided
var blockingCollection = new BlockingCollection<String>();
// generate items and add them to the collection
Task.Factory.StartNew(() => {
for (int i = 0; i < 100; i++) {
blockingCollection.Add("value" + i);
}
// mark adding as complete so the foreach loops
// below will exit when the collection is empty
blockingCollection.AddingComplete();
});
// create worker 1 to process items
Task.Factory.StartNew(() => {
foreach (string value in blockingCollection.GetConsumingEnumerable()) {
Console.WriteLine("Worker 1: " + value);
}
});
// create worker N to process items
Task.Factory.StartNew(() => {
foreach (string value in blockingCollection.GetConsumingEnumerable()) {
Console.WriteLine("Worker N: " + value);
}
});
這裏是一個很好的頁面瞭解更多關於它,看到其他的例子:http://www.codethinked.com/blockingcollection-and-iproducerconsumercollection
爲什麼不使用併發生產者/消費者集合,其中值是通過一些外部源增加,以及每5個線程在準備好處理另一個項目時將取消一個值。 – Paccc
[ConcurrentQueue](http://msdn.microsoft.com/en-us/library/dd267265(v = vs.110).aspx)對我來說似乎是一個很好的解決方案!另外,你能否給我們一個[SSCCE](http://www.sscce.org/)? –
因此使用ConcurrentQueue的解決方案比任務更好? – senzacionale