繁体   English   中英

了解TPL数据流,块和延续任务

[英]Understanding TPL Dataflow, Blocks, and Continuation Tasks

我正在一个需要满足TPL Dataflow理想情况的项目中工作。 由于对它的经验相对有限(并且我之前做过的事情),我一直在阅读Microsoft的文档以及可以在网上找到的文章来进行梳理。

完成此操作后,我构建了将一系列块链接在一起的代码(主要是TransformBlock并以一个ActionBlock结尾,如下所示:

var block1 = new TransformBlock<T, U>(async input => {});
var block2 = new TransformBlock<U, V>(async input => {});
var block3 = new ActionBlock<V>(async input => {});

block1.LinkTo(block2);
block2.LinkTo(block3);

foreach(var item in items)
{
   await block1.SendAsync(item);
}
block1.Complete();
await block3.Completion;

文章中的某人(我找不到)建议管道中应该有继续任务,以将块标记为已完成。 这是他们为此提供的代码。

// Create the continuation tasks in the pipeline that marks each block as complete.
await block1.Completion.ContinueWith(t =>
{
    if (t.IsFaulted) { ((IDataflowBlock)block2).Fault(t.Exception); }
    else { block2.Complete(); }
});
await block2.Completion.ContinueWith(t =>
{
    if (t.IsFaulted) { ((IDataflowBlock)block3).Fault(t.Exception); }
    else { block3.Complete(); }
});

我承认我不完全了解此代码的功能以及是否需要它。 当我尝试在我刚刚编写的代码中运行此代码时,该代码将挂在第一个ContinueWith ,并且永远不会使其运行管道。

我希望能得到更多的解释,因为我想更好地了解这里发生的细微差别。

对于线性管道,您所需要做的就是PropagateCompletion 该选项会传播“ Completion ”以及“ Faults ,然后将其异常附加到最终“ Completion Task

var linkOptions = new DataflowLinkOptions() { PropagateCompletion = true };
block1.LinkTo(block2, linkOptions);
block2.LinkTo(block3, linkOptions);

继续是不必要的。 但是,如果您有分配给多个块的管道,则需要自己处理完成和错误传播,如下所示

该代码挂在第一个ContinueWith

发生这种情况是因为您await继续,所以如果您在调用Complete()之前这样做,那么block1将永远不会完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM