Using the BlockingCollection for thread-safe producer-consumer scenarios in .NET Part 5
September 15, 2015 Leave a comment
In the previous post we finished the basics of building producer-consumer scenarios with BlockingCollection in .NET. In particular we saw how to send a signal to the consumer that the producers have completed their tasks and no more items will be inserted into the work queue.
In this final post I just want to draw your attention to a couple of other fine-tuning methods in the BlockingCollection object.
Upper limit on blocking collection size
The BlockingCollection constructor allows you to set an upper limit of elements stored in the underlying producer-consumer collection:
new BlockingCollection<WorkTask>(workTaskCollection, 5);
If this upper limit is reached then the producer won’t be able to add new items to the collection until a consumer has retrieved one from it. This implies that BlockingCollection.Add method will block the current thread until there’s enough space in the producer-consumer collection. This brings us to the next section.
TryAdd
BlockingCollection has a TryAdd method which returns true if the insertion was successful. Its parameterless version will return immediately with true or false. You can also provide a wait time during which the TryAdd method can try to add an item to the collection. In the following example TryAdd will wait for at most 10 seconds before returning:
bool insertionSuccess = _workQueue.TryAdd(workTask, 10000);
TryTake
The counterpart of TryAdd is BlockingCollection.TryTake. It returns true if the item retrieval was successful and also returns the item as an “out” parameter. The most simple overload will return immediately without blocking the current thread:
WorkTask workTask; bool success = _workQueue.TryTake(out workTask);
You can also specify a maximum wait time in milliseconds before returning the result:
WorkTask workTask; bool success = _workQueue.TryTake(out workTask, 10000);
View the list of posts on the Task Parallel Library here.