理解 TPL 数据流并行度排序 [英] Understanding TPL Dataflow Degree of Parallelism ordering

查看:38
本文介绍了理解 TPL 数据流并行度排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 Dataflow (任务并行库),并且有一部分说:

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

当您指定的最大并行度大于 1 时,会同时处理多条消息,因此,消息可能不会按照接收顺序进行处理.但是,从块中输出消息的顺序将是正确排序的.

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.

什么意思?

例如,我将操作块设置为并行度 = 5:

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();

我的 Producer() 基本上是将数字排入区块:

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();
}

我的消费者(i)只是写出这些行:

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);
}

这是否意味着 Consumer(2) 将被阻塞,直到 Consumer(1) 完成处理(因为有 5 秒的延迟)?我测试了代码,但似乎并非如此.即使我删除了 5 秒延迟,我也没有看到输出是有序的.

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.

[更新]

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() 现在将添加到 bBlock:

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();
}

那么,在这种情况下,Consumer(1) 将等待 5 秒,然后 Consumer(2) 才能继续?

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

推荐答案

没有.您可以将 DoP 视为线程(不完全但简单的方式来考虑它)

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

所以在 5 处,它会尝试一次处理 5 个.由于#1 需要 5 秒,#2 肯定会先完成.#3、#4 和 #5 可能也是如此.甚至可能是 #6(因为 #2 已经完成,DoP 将允许它从 #6 开始)

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)

即使没有延迟,也不能保证处理的顺序.所以永远不要依赖他们执行的顺序.话虽如此,当您使用消息输出(NOT 打印,因为这是它们执行的顺序)时,它们将按照它们进来的顺序重新排序,即使它们以任意方式执行订购.

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.

这篇关于理解 TPL 数据流并行度排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆