即使在调用 "Complete()" 之后,C# TransformBlock 也不会 运行

C# TransformBlock doesn't run even after calling "Complete()"

我得到了这个代码片段,尝试使用 TransformBlock 开始执行代码,如下所示:

public static void Main(string[] args)
{
    var multiplyBlock = new TransformBlock<int, int>(x => x * 2);
    var additionBlock = new TransformBlock<int, int>(x => x + 2);
    multiplyBlock.LinkTo(additionBlock, new DataflowLinkOptions { PropagateCompletion = true });
    multiplyBlock.Post(3);
    additionBlock.Completion.ContinueWith(x => Console.WriteLine(x));

    multiplyBlock.Complete();
    additionBlock.Completion.Wait();
}

但是当我 运行 这段代码时,它挂起并且什么都不打印。我尝试调试它,我发现所有代码行都已完成,但在函数结束时,程序挂起。那么这里发生了什么,以及如何解决它?

谢谢。

您需要使用 ActionBlock 来使用 TransFormBlock 的输出,如下所示:

public static void Main(string[] args)
{
    var multiplyBlock = new TransformBlock<int, int>(x => x * 2);
    var additionBlock = new TransformBlock<int, int>(x => x + 2);
    var outputBlock   = new ActionBlock<int>(Console.WriteLine);

    multiplyBlock.LinkTo(additionBlock, new DataflowLinkOptions { PropagateCompletion = true });
    additionBlock.LinkTo(outputBlock,   new DataflowLinkOptions { PropagateCompletion = true });

    multiplyBlock.Post(3);

    multiplyBlock.Complete();
    outputBlock.Completion.Wait();
}

如果您只是尝试使用 TransformBlock 什么也不会发生,因为没有任何东西可以消耗所有输出。

这样想:TransformBlock 有一个输入和一个输出,所以必须以某种方式消耗输出。一个 ActionBlock 只有一个输入,它会随着 TransformBlock 的输出被重复调用。 (这有点过于简单化,但它应该有助于您理解接线。)

在上面的示例中,乘法块的输出连接到加法块的输入,加法块的输出连接到输出块的输入。

乘法块的输入必须来自某个地方,这里它来自对 multiplyBlock.Post(3);.

的调用

(实际上,如果您想显式使用 TransformBlock 的输出,您可以通过在循环中调用 TransformBlock.Receive()(或其他接收方法之一)来处理数据,但这不是必需的,因为使用 ActionBlock 来使用转换后的数据要容易得多。)

This documentation 可能对你有用。