6

Assuming the BlockingCollection is using a ConcurrentQueue underneath, when could the TryTake(T, Int32) method return false if you are using Timeout.Infinite?

Gyrien
  • 317
  • 3
  • 8
  • 2
    The document you linked to contains the answer to your question. What are you looking for in an answer? A concrete example? Code that will fail? The docs clearly state what will cause the method to throw. – evanmcdonnal Jan 17 '14 at 20:29
  • 2
    Or, instead, are you asking when it would return `false` instead of throwing an exception? – Sven Grosen Jan 17 '14 at 20:33
  • @ledbutter That is what I am asking, I have updated the OP. – Gyrien Jan 17 '14 at 20:46
  • @elgonzo So in this case there is not a situation in which it would return false barring the listed exceptions in the msdn link? – Gyrien Jan 17 '14 at 20:47

2 Answers2

14

Here's a simple example that shows when it can return false: when the collection is marked as CompleteAdding and becomes emptу

//by default, BlockingCollection will use ConcurrentQueue
BlockingCollection<int> coll = new BlockingCollection<int>();

coll.Add(1);
coll.Add(2);
coll.CompleteAdding();

int item;

if (coll.TryTake(out item, -1))
{
    Console.WriteLine(item);
}

if (coll.TryTake(out item, -1))
{
    Console.WriteLine(item);
}

if (coll.TryTake(out item, -1))
{
    //this won't get hit
}
else
{
    Console.WriteLine("TryTake returned false!");
}

This allows you to forbid adding new items in queue and complete processing of remaining elements

Gleb Sevruk
  • 494
  • 5
  • 9
Sven Grosen
  • 5,616
  • 3
  • 30
  • 52
  • If you do not trigger with .CompleteAdding(), it will not return false though, correct? – Gyrien Jan 17 '14 at 21:08
  • 1
    @Gyrien correct, but it won't ever get past the last `TryTake` call (assuming you use an infinite timeout) as it will wait there until you signal that you are done adding to the collection. – Sven Grosen Jan 17 '14 at 21:09
7

This will print false :

 var coll = new BlockingCollection<int>();            

 coll.CompleteAdding();   // closed for business

 int v;
 bool result = coll.TryTake(out v, Timeout.Infinite);

 Console.WriteLine(result);

So basically a BlockingCollection supports 2 separate concepts: Empty and Closed. And while TryTake() can wait forever on an Empty queue, when the queue is both Empty and Closed it will return false.

H H
  • 263,252
  • 30
  • 330
  • 514