C#TPL数据流-完成不工作

C#TPL数据流-完成不工作,c#,task-parallel-library,pipeline,tpl-dataflow,C#,Task Parallel Library,Pipeline,Tpl Dataflow,此代码永远不会到达最后一行,因为完成不会从saveBlock传播到sendBlock。我做错了什么 var readGenerateBlock = new TransformBlock<int, int>(n => { Console.WriteLine("Read " + n); Thread.Sleep(15); return n; }); var groupingBlock = new BatchBlock

此代码永远不会到达最后一行,因为完成不会从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.");
var readGenerateBlock=newtransformblock(n=>
{
控制台写入线(“读取”+n);
睡眠(15);
返回n;
}); 
var groupingBlock=新批块(10);
var saveBlock=new TransformManyBlock(n=>
{
WriteLine(“保存{0}项[{1};{2}]”,n.Count(),n.First(),n.Last());
睡眠(150);
返回n;
}); 
var sendBlock=新转换块(n=>
{
WriteLine(“发送{0}”,n);
睡眠(25);
返回n;
},新的ExecutionDataflowBlockOptions{MaxDegreeOfParallelism=2});
LinkTo(groupingBlock,新的DataflowLinkOptions{PropagateCompletion=true});
LinkTo(saveBlock,新的DataflowLinkOptions{PropagateCompletion=true});
LinkTo(sendBlock,newdataflowlinkoptions{PropagateCompletion=true});
对于(0250,i=>readGenerateBlock.Post(i));
readGenerateBlock.Complete();
sendBlock.Completion.Wait();
Console.WriteLine(“已完成”);

必须先从块中读取数据,然后才能完成。由于没有人正在读取
saveBlock
,因此它将永远无法完成


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

根据官方文档:“'s向System.Threading.Tasks.Dataflow.IDataflowBlock发出信号,表示它不应接受、不应生成任何消息,也不应使用任何延迟的消息。'*然而,你说的是真的,听起来有点矛盾。”