【问题标题】:What is the exact difference between Task.ContinueWith and ActionBlock.LinkTo?Task.ContinueWith 和 ActionBlock.LinkTo 之间的确切区别是什么?
【发布时间】:2018-03-26 10:52:52
【问题描述】:

我是 TPL Dataflow ActionBlockTransformBlock 等的新手。我曾经练习 Task.ContinueWith() 在需要时创建管道。我最近开始练习 TPL 数据流及其块。

但是我对这两者之间的确切区别有点困惑。那你能告诉我什么时候用什么吗?

【问题讨论】:

    标签: c# task-parallel-library .net-4.5 tpl-dataflow


    【解决方案1】:

    这是两种不同的方法,它们具有相似的行为,但实际上并不相互关联。 ContinueWithTask 安排延续。使用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 块之间创建一个一次性链接。该链接可以通过多种方式配置see 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 仅适用于数据流块,应被视为与延续分开的东西,用于构建数据流网络。

    【讨论】:

    • 感谢您的回答
    猜你喜欢
    • 2016-01-19
    • 2013-03-25
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多