Domanda

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!

È stato utile?

Soluzione

.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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top