Basic producer-consumer loop BlockingCollection
suggest changevar collection = new BlockingCollection<int>(5); var random = new Random(); var producerTask = Task.Run(() => { for(int item=1; item<=10; item++) { collection.Add(item); Console.WriteLine("Produced: " + item); Thread.Sleep(random.Next(10,1000)); } collection.CompleteAdding(); Console.WriteLine("Producer completed!"); });
It is worth noting that if you do not call collection.CompleteAdding();
, you are able to keep adding to the collection even if your consumer task is running. Just call collection.CompleteAdding();
when you are sure there are no more additions. This functionality can be used to make a Multiple Producer to a Single Consumer pattern where you have multiple sources feeding items into the BlockingCollection and a single consumer pulling items out and doing something with them. If your BlockingCollection is empty before you call complete adding, the Enumerable from collection.GetConsumingEnumerable()
will block until a new item is added to the collection or BlockingCollection.CompleteAdding(); is called and the queue is empty.
var consumerTask = Task.Run(() => { foreach(var item in collection.GetConsumingEnumerable()) { Console.WriteLine("Consumed: " + item); Thread.Sleep(random.Next(10,1000)); } Console.WriteLine("Consumer completed!"); }); Task.WaitAll(producerTask, consumerTask); Console.WriteLine("Everything completed!");
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents