我是TPL数据流的新手 ActionBlock
, TransformBlock
等。我曾经练习过 Task.ContinueWith()
以在需要时创建一个管道。最近我开始练习关于TPL Dataflow和它的块。
但我对这两者之间的具体区别有点困惑。所以请你告诉我什么时候用什么?
这是两个独立的方法,它们有类似的行为,但实际上彼此没有关系。ContinueWith
安排一个延续的方法 Task
. 随着 async/await
你应该不需要真正使用 ContinueWith
自从 async/await
关键字已经将你的方法的其余部分安排为延续。例如这两个方法 AsyncAwait
和 Continuation
产生同样的结果。
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
仅适用于数据流块,应被视为与连续体分开的东西,用于构建数据流网络。