TPL数据流块永远不会在PropagateCompletion上完成

时间:2015-06-19 10:25:27

标签: c# .net task-parallel-library dataflow tpl-dataflow

自从我的传播完成管道的最后一次更改以来,我的一个缓冲区块永远不会完成。让我总结一下什么在起作用,什么不再起作用:

以前的工作:

A.LinkTo(B, PropagateCompletion);
B.LinkTo(C, PropagateCompletion);
C.LinkTo(D, PropagateCompletion);
D.Receive();

// everything completes

不再有效

A.LinkTo(B, PropagateCompletion);
C.LinkTo(D, PropagateCompletion);

await A.Completion;
someWriteOnceBlock.Post(B.Count);
// B.Complete(); commented on purpose
B.LinkTo(C, PropagateCompletion);

D.Receive();

// Only A reaches completion
// B remains in 'waiting for activation'
// C executes but obviously never completes since B doesn't either

如果我取消注释注释行,一切正常,但显然该行不是必需的。

不知何故,我的BufferBlock B永远不会完成,即使链接的块已完成并传播完成,而链接的块接收所有缓冲的项目

2 个答案:

答案 0 :(得分:0)

等待A完成A执行剩余代码,直到A完成。这就是等待的工作原理 - 它之后的代码被包装在一个续集中,准备完成等待的代码。所以在这种情况下,A在A完成后链接到A,所以我认为完成不会传播。

答案 1 :(得分:0)

我遇到了同样的问题 - 我的最后一个块是一个只是坐在那里等待完成的TransformBlock。

只有在没有剩余输入要处理的情况下,一个块才会完成,它的所有输出都已处理完毕,并且已经完成,可以通过调用block.Complete来完成,也可以在链中传播完成。

我通过制作最终块和ActionBlock来修复此问题,因为这不会产生任何输出。这是我的代码,它接受一系列文本文件并反序列化它们的内容:

Dim maxDop = Environment.ProcessorCount
Dim executionOptions = New ExecutionDataflowBlockOptions With {.MaxDegreeOfParallelism = maxDop}
Dim linkOptions = New DataflowLinkOptions With {.PropagateCompletion = True}

Dim inputBlock = New BufferBlock(Of String)
Dim transformBlock = New TransformBlock(Of String, IEnumerable(of JsonObject))(Function(fileName) DeserialiseFromFileAsync(fileName)
Dim outputBlock As New BufferBlock(Of IEnumerable(of JsonObject))
Dim combineBlock = New ActionBlock(Of IEnumerable(of JsonObject))(Sub(col) ' Do something to add all the collections together)

inputBlock.LinkTo(transformBlock, linkOptions)
transformBlock.LinkTo(outputBlock, linkOptions)
outputBlock.LinkTo(combineBlock, linkOptions)

For fileNo = 1 To 10
    inputBlock.Post(String.Concat("JsonFile", fileNo, ".txt"))
Next

inputBlock.Complete() 'Complete the first block, propogation will handle the rest
Await combineBlock.Completion 'Await the last block completing