Question

I'm using a BlockingCollection to insert some values that are processed using some threads.

Sometimes I have to take a "snapshot" of this collection to check some results.. so I do something like this:

IEnumerable<SourceResult> response = m_response.GetConsumingEnumerable();
IEnumerable<string>       results  = response.Where(i => i.source == "TEST1" || i.source == "TEST2").Select(i => i.json).DefaultIfEmpty(null);

if (results != null && results.Count() > 0)
{
    // CODE
}

When the code reaches this IF statement, the application freezes.

Why? Seems that response is locked forever.

Any ideas? What am I doing wrong?

Thank you very much!

Was it helpful?

Solution

.GetConsumingEnumerable() produces the "blocking" enumerable that the collection gets its name from. In short you are using the wrong collection.

The way you use BlockingCollection is to put a thread on it to run a loop.

foreach(var item in blockingCollection.GetConsumingEnumerable())
{
    //do some work
}

Then using other threads you place objects onto the blocking collection. It is called a "blocking collection" because its enumerator blocks (sleeps) when it hits the last objects and then waits until a new item is added to the list.

The only way out of the for each loop is you call .CompleteAdding() on the blocking collection. Since IEnumerable.Count() is in effect just...

var count = 0;
foreach(var item in list)
{
   count++;
}
return count;

Your code is blocking on a foreach loop in the if statement (and waiting for you to call .CompleteAdding()).

I suspect you ACTUALLY wanted something more like ConcurrentBag.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top