Task.ContinueWith和ActionBlock.LinkTo的具体区别是什么?

问题描述 投票:-1回答:1

我是TPL数据流的新手 ActionBlock, TransformBlock 等。我曾经练习过 Task.ContinueWith() 以在需要时创建一个管道。最近我开始练习关于TPL Dataflow和它的块。

但我对这两者之间的具体区别有点困惑。所以请你告诉我什么时候用什么?

c# task-parallel-library .net-4.5 tpl-dataflow
1个回答
2
投票

这是两个独立的方法,它们有类似的行为,但实际上彼此没有关系。ContinueWith 安排一个延续的方法 Task. 随着 async/await 你应该不需要真正使用 ContinueWith 自从 async/await 关键字已经将你的方法的其余部分安排为延续。例如这两个方法 AsyncAwaitContinuation 产生同样的结果。

public async Task AsyncAwait()
{
    await DoAsync();
    DoSomethingElse();
}

public async Task Continuation()
{
    await DoAsync().ContinueWith(_ => DoSomethingElse());
}

public Task DoAsync() => Task.Delay(TimeSpan.FromSeconds(1));

public void DoSomethingElse()
{
    //More Work
}

LinkTo 另一方面,在两件事情之间建立了一个一次性的联系。Tpl-Dataflow 块。该链接可以通过多种方式进行配置。参见DatflowLinkOptions. 其中最多配置的项目是 PropagateCompletion. 正如你希望看到的那样,一个数据流链接可以比简单的延续更多。你可以通过完成,添加一个谓词来过滤数据,甚至可以将块链接到一个复杂的结构中,如网格或反馈循环。此外,数据流链接还允许你设置 "背压 "来节流。如果下游块变得过载,它的输入缓冲区被填满,上游块可以暂停处理。数据流链接的完整行为不容易通过手工实现连续性。

public ITargetBlock<int> BuildPipeline()
{
    var block1 = new TransformBlock<int, int>(x => x);
    var block2 = new ActionBlock<int>(x => Console.WriteLine(x));
    block1.LinkTo(block2 , new DataflowLinkOptions() { PropagateCompletion = true });
    return block1;
}

除非你要做复杂的链接,否则你应该总是倾向于使用 async/await 在原始的连续性上。async/await 使代码更容易编写、理解和维护。LinkTo 仅适用于数据流块,应被视为与连续体分开的东西,用于构建数据流网络。

© www.soinside.com 2019 - 2024. All rights reserved.