I have a situation where I have a producer / consumer scenario. The manufacturer never stops, which means that even if there is a time when there are no elements in BC, additional elements can be added later.
Moving from the .NET Framework 3.5 to 4.0, I decided to use it BlockingCollectionas a parallel queue between the consumer and the manufacturer. I even added some parallel extensions, so I could use BC with Parallel.ForEach.
The problem is that in the consumer stream I need a hybrid model:
- I always check BC to process any item that arrived with
Parallel.ForEach(bc.GetConsumingEnumerable(), item => etc - Inside this,
foreachI perform all tasks that are independent of each other. - That is the problem. After parallelizing the previous tasks, I need to manage their results in the same FIFO order in which they were in BC. Processing of these results should be carried out in a synchronization stream.
The following is a small example in pseudo code:
manufacturer:
private void Current_OnPageScanned(object sender, ScannedPage scannedPage)
{
_concurrentCollection.TryAdd(scannedPage);
}
Consumer
private void Init()
{
_cancelTasks = false;
_checkTask = Task.Factory.StartNew(() =>
{
while (!_cancelTasks)
{
var bc = _concurrentCollection;
Parallel.ForEach(bc.GetConsumingEnumerable(), item =>
{
ScannedPage currentPage = item;
});
}
});
}
Obviously, this work does not work, because the block is .GetConsumingEnumerable()blocked until there is no other element in BC. I would like to do this with tasks and just run 4 or 5 tasks in one batch, but:
- , , BC ( , . - BC, 4
TryTake , , , , , BC , , , BC, 4 )? - , Parallel.For?
- FIFO, BC?
- - concurrency, ?
- , , - StackOverflow, , - , , .