问题
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?
回答1:
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.
回答2:
The DataflowBlockOptions
class contains a configurable property EnsureOrdered:
Gets or sets a value that indicates whether ordered processing should be enforced on a block's handling of messages.
This property determines if the block will output the processed messages in the same order it received them, and by default is true
. So blocks like the TransformBlock and the TransformManyBlock that produce an output (implement the ISourceBlock<TOutput> interface) are preserving the original order of the received messages when propagating them to their targets blocks (the ITargetBlock<TInput> blocks they are linked to).
The EnsureOrdered
option has nothing to do with the order in which the messages are processed. For example setting the property MaxDegreeOfParallelism to the value DataflowBlockOptions.Unbounded means that all received messages will be scheduled for execution immediately upon arrival, and —provided that the ThreadPool has enough threads available— the execution of all of them will start immediately. Setting the EnsureOrdered
to false
will have the effect that as soon as the execution of a message is completed it will be eligible for propagation downstream, even if the execution of a message received earlier has not been completed yet.
The EnsureOrdered
option has no effect to ActionBlocks because these blocks do not produce an output. It also has no effect to BufferBlocks because, although these blocks produce output, they don't do any processing, so nothing happens that could distort the original order of the messages they received. In short this property has effect only for blocks that produce output and perform processing.
来源:https://stackoverflow.com/questions/39172554/understanding-tpl-dataflow-degree-of-parallelism-ordering