Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding TPL Dataflow Degree of Parallelism ordering

Tags:

I was reading Dataflow (Task Parallel Library), and there is a portion which says:

When you specify a maximum degree of parallelism that is larger than 1, multiple messages are processed simultaneously, and therefore, messages might not be processed in the order in which they are received. The order in which the messages are output from the block will, however, be correctly ordered.

What does it means?

Example, I set my action block with degree of parallelism = 5:

testActionBlock = new ActionBlock<int>(i => Consumer(i),
            new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = 5
            });

await Producer();
testActionBlock.Completion.Wait();

My Producer() basically queue numbers into the block:

private async Task Producer()
{
    for (int i=0; i<= 1000; i++)
    {
        await testActionBlock.SendAsync(i);
    }
    testActionBlock.Complete();
}

And my Consumer(i) just write out the lines:

private async Task Consumer(int i)
{
    if (i == 1)
    {
        await Task.Delay(5000);
    }
    Console.WriteLine(i);
}

Does it means that Consumer(2) will be blocked until Consumer(1) has finished processing (since there is a 5 sec delay)? I tested out the code and it doesn't seems to be the case. Even when I removed the 5 sec delay, I don't see the output to be in order.

[Update]

bBlock = new BufferBlock<int>(option);

testActionBlock = new ActionBlock<int>(i => Consumer(i),
    new ExecutionDataflowBlockOptions()
    {
        MaxDegreeOfParallelism = 5
    });

bBlock.LinkTo(testActionBlock);

await Producer();
testActionBlock.Completion.Wait();

My Producer() now will add to the bBlock:

private async Task Producer()
{
    for (int i=0; i<= 1000; i++)
    {
        await bBlock.SendAsync(i);
    }
    bBlock.Complete();
}

So, in this case, Consumer(1) will await for 5 sec, before Consumer(2) can proceed?

like image 894
SimonSays Avatar asked Aug 26 '16 18:08

SimonSays


1 Answers

No. DoP you can think of as threads (Not exactly but easy way to think of it)

So at 5, it will try to process 5 at a time. Since the #1 is taking 5 seconds, #2 will certainly finish first. Likely so will #3, #4, and #5. Probably even #6 (since #2 is done, the DoP will allow it to start on #6)

Even without a delay, there is no guaranteed order to the processing. So never depend on the ORDER THAT THEY EXECUTE. Having said that, when you use the message outputs (NOT prtinting, as that is order that they execute) they will be re-sorted in the order that they came in, even though they executed in an arbitrary order.

like image 187
Tim Avatar answered Sep 26 '22 14:09

Tim