What is the difference between solution 1 and 2, _taskQ is BlockingCollection and I am trying to implement a Producer-Consumer scenario. The BlockingCollection uses the default ConcurrentQueue for internal storage.
//Solution 1
foreach (Action action in _taskQ.GetConsumingEnumerable())
{
action(); // Perform task.
Thread.Sleep(1000);
}
TryTake blocks when there is no item
//Solution 2
Action t;
while(_taskQ.TryTake(out t))
{
t();
Thread.Sleep(1000);
}
bool TryTake(out T)
returns false immediately if there are no items.
bool TryTake(out T, TimeSpan)
returns false if there are no items within the timeout period.
The enumerable returned by GetConsumingEnumerable()
blocks while it has no items, until a producer calls CompleteAdding()
.
In Solution 1, you wait for the next action and execute it; a suitable pattern! But the Thread.Sleep()
is not really necessary because the iteration will block if there are no items anyway.
In Solution 2, you take and execute actions while there are any, then exit the loop if the consumer gets ahead of the producer. That's probably not what you want.