完成未在数据流块之间传播

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

我正在学习数据流基础知识。 这是一个代码示例,对我来说看起来正确,但不起作用。 它不会返回结果整数值,而是冻结。 根据我的理解,这是因为完成不会在块之间传播。

    public static int Process(int value)
    {
        var multiplyBlock = new TransformBlock<int, int>(item => item * 2);
        var subtractBlock = new TransformBlock<int, int>(item => item - 2);

        var options = new DataflowLinkOptions() { PropagateCompletion = true };
        multiplyBlock.LinkTo(subtractBlock, options);

        multiplyBlock.Post(value);

        multiplyBlock.Complete();
        subtractBlock.Completion.Wait(); // <--- code freezes here

        return subtractBlock.Receive();
    }

您能帮我了解缺少的内容吗?

c# tpl-dataflow
1个回答
0
投票

当上游

subtractBlock.Complete()
完成时,会自动调用
multiplyBlock.Completion
(因为
PropagateCompletion = true 
)。此时
subtractBlock.Completion
将不会立即完成。当以下两个条件同时成立时,它将完成:

  1. subtractBlock
    的输入缓冲区中的所有项目均已处理完毕。
  2. subtractBlock
    的输出缓冲区中的所有项目已被下游的块接受。

换句话说,

TransformBlock<TInput, TOutput>
的输入和输出缓冲区都必须为空,否则该块将永远不会完成。在您的情况下,块的输出缓冲区未清空,因为该块未链接到任何内容。您可以通过将其链接到
NullTarget
或将其替换为
ActionBlock<TInput>
来解决此问题。

顺便说一句,请注意,目前 TPL 数据流库存在一个错误,在非常特定和罕见的情况下,可能会导致管道永远无法完成。您可以在here找到此错误的演示。这个错误一直存在,不太可能很快得到解决。

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