Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to take an item from a BlockingCollection?

When calling BlockingCollection.Take() it is possible for the IsCompleted status of the collection to change between the check of IsCompleted and the call to Take().

The MSDN Documentation that shows an example just catches the invalid operation exception, but it seems like there must be a proper way to do such a call without catching the exception (since this incurs a decent amount of overhead and doesn't look clean in code). What is the proper way to call .Take() and to avoid an invalid operation exception?

A simplified version of my specific issue:

If (!blockingCollection.IsCompleted)
{
//do some stuff
value = blockingCollection.Take();  //Throws Exception, IsCompleted = True;
}

There is a TryTake method available, but I am under the impression that it is so that a timeout and cancelation token can be passed in, not to deal with the IsCompleted becoming true in between the time it is checked and when Take() is called.

like image 575
wllmsaccnt Avatar asked Aug 18 '11 16:08

wllmsaccnt


People also ask

How to use BlockingCollection c#?

If you want to add elements to a BlockingCollection<T> in C#, then you need to use the following methods of the BlockingCollection<T> class. Add(T item): This method is used to add the item to the BlockingCollection. Add method takes a single parameter i.e. the item to be added to the collection.

Is BlockingCollection thread-safe?

BlockingCollection<T> is a thread-safe collection class that provides the following features: An implementation of the Producer-Consumer pattern. Concurrent adding and taking of items from multiple threads.

Is Blockcollection a FIFO?

That being said, BlockingCollection<T> works upon any IProducerConsumerCollection<T> (specified in the constructor). If you don't provide one in the constructor, internally, it will use a ConcurrentQueue<T> . This causes it to be FIFO, since it will actually be (internally) a queue.


1 Answers

You can use the TryTake overload with no timeout/cancelation. It will return false if the BlockingCollection is empty or has been marked completed, and handles the synchronization issue you're facing correctly.

like image 146
Reed Copsey Avatar answered Sep 22 '22 19:09

Reed Copsey