【问题标题】:C# TransformBlock is not executed after calling Complete function调用 Complete 函数后不执行 C# TransformBlock
【发布时间】:2020-03-11 12:16:08
【问题描述】:

我有这个代码sn-p:

static void Main(string[] args)
{
    var printResult = new ActionBlock<int>(x =>
    {
        Console.WriteLine(x);
    });
    var countBytes = new TransformBlock<int, int>(
        new Func<int, int>((x)=> { return 2 * x; }));
    countBytes.LinkTo(printResult, new DataflowLinkOptions { PropagateCompletion = true });
    countBytes.Completion.ContinueWith(delegate { printResult.Complete(); });
    countBytes.Complete();
    printResult.Completion.Wait();
    Console.ReadKey();
}

我预计TransformBlock的代码

return 2*x

会运行,然后打印结果,但实际上什么也没打印。我在里面设置了一个断点

printResult

Console.WriteLine 上的函数对象,但它没有被介入。

为什么没有打印出来,我在哪里出错以及如何解决?

【问题讨论】:

  • 你还没有向任何一个区块发布任何内容
  • countBytes.Completion.ContinueWith(delegate { printResult.Complete(); }); 行做了PropagateCompletion = true 已经做的事情
  • 你应该在调用countBytes.Complete();之前添加countBytes.Post(123);
  • 代码块似乎是从这里复制的:docs.microsoft.com/en-us/dotnet/standard/parallel-programming/…,因此有趣的是缺少以下行:countBytes.Post(tempFile);

标签: c# parallel-processing tpl-dataflow


【解决方案1】:

您缺少告诉countBytes 将完成传播到链接块的设置(尝试使用 ContinueWith() 完成链接块是错误的做法)。

此外,如果您不向管道发布任何内容,则不会有任何输出。

试试这个:

static void Main(string[] args)
{
    var printResult = new ActionBlock<int>(x =>
    {
        Console.WriteLine(x);
    });

    var countBytes = new TransformBlock<int, int>(new Func<int, int>((x) => { return 2 * x; }));

    countBytes.LinkTo(printResult, new DataflowLinkOptions { PropagateCompletion = true });
    countBytes.Post(1);
    countBytes.Completion.ContinueWith(task => Console.WriteLine("countBytes has completed"));
    printResult.Completion.ContinueWith(task => Console.WriteLine("printResult has completed"));
    countBytes.Complete();
    printResult.Completion.Wait();
    Console.WriteLine("Done");
    Console.ReadLine();
}

如果你运行它,输出是:

2
countBytes has completed
Done
printResult has completed

(注意“printResult has completed”是如何在“Done”之后输出的。这是因为在printResult.Completion 发出信号之后安排继续。)

如果您像这样注释掉new DataflowLinkOptions { PropagateCompletion = true }

countBytes.LinkTo(printResult /*, new DataflowLinkOptions { PropagateCompletion = true } */);

那么输出将是:

2
countBytes has completed

请注意,不会打印“完成”,因为如果完成没有传播到该块,printResult.Completion.Wait() 永远不会返回。

【讨论】:

    猜你喜欢
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 2014-06-10
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    相关资源
    最近更新 更多