C# TPL Dataflow - 完成状态无效

3

这段代码永远不会执行到最后一行,因为完成状态无法从saveBlock传递到sendBlock。我做错了什么?

var readGenerateBlock = new TransformBlock<int, int>(n =>
    {
        Console.WriteLine("Read " + n);
        Thread.Sleep(15);
        return n;
    }); 
var groupingBlock = new BatchBlock<int>(10);
var saveBlock = new TransformManyBlock<int[], int>(n =>
    {
        Console.WriteLine("Saving {0} items [{1}; {2}]", n.Count(), n.First(), n.Last());
        Thread.Sleep(150);
        return n;
    }); 
var sendBlock = new TransformBlock<int, int>(n =>
    {
        Console.WriteLine("Sending {0}", n);
        Thread.Sleep(25);
        return n;
    }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 }); 

readGenerateBlock.LinkTo(groupingBlock, new DataflowLinkOptions { PropagateCompletion = true });
groupingBlock.LinkTo(saveBlock, new DataflowLinkOptions { PropagateCompletion = true });
saveBlock.LinkTo(sendBlock, new DataflowLinkOptions { PropagateCompletion = true });

Parallel.For(0, 250, i => readGenerateBlock.Post(i));
readGenerateBlock.Complete();

sendBlock.Completion.Wait();
Console.WriteLine("Completed.");
1个回答

8

在块完成之前,您必须从块中读取数据。由于没有人读取 saveBlock,它永远不会完成。

如果您不需要这些数据,则最简单的解决方案是使用ActionBlock而不是TransformBlock。否则,请继续阅读数据,直到块完成。


根据官方文档:*' 向 System.Threading.Tasks.Dataflow.IDataflowBlock 发送信号,表明它不应该再接受或产生任何消息,也不应该再消耗任何延迟的消息。'* 然而,您所说的是真实的,听起来有点矛盾。 - Martin Meeser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接