【发布时间】:2012-11-28 13:50:08
【问题描述】:
鉴于以下情况:
BufferBlock<int> sourceBlock = new BufferBlock<int>();
TransformBlock<int, int> targetBlock = new TransformBlock<int, int>(element =>
{
return element * 2;
});
sourceBlock.LinkTo(targetBlock, new DataflowLinkOptions { PropagateCompletion = true });
//feed some elements into the buffer block
for(int i = 1; i <= 1000000; i++)
{
sourceBlock.SendAsync(i);
}
sourceBlock.Complete();
targetBlock.Completion.ContinueWith(_ =>
{
//notify completion of the target block
});
targetBlock 似乎永远不会完成,我认为原因是TransformBlock targetBlock 中的所有项目都在输出队列中等待,因为我没有将targetBlock 链接到任何其他数据流块。但是,我真正想要实现的是当 (A) targetBlock 被通知完成并且 (B) 输入队列为空时的通知。我不想关心项目是否仍然位于TransformBlock 的输出队列中。我该怎么办?获得我想要查询sourceBlock 的完成状态并确保targetBlock 的InputCount 为零的唯一方法是什么?我不确定这是否非常稳定(sourceBlock 是否真的只有在sourceBlock 中的最后一项已传递给targetBlock 时才标记为已完成?)。有没有更优雅、更有效的方法来实现相同的目标?
编辑:我刚刚注意到,即使是“肮脏”的方式来检查 sourceBlock 和 InputCount 的完成情况,targetBlock 为零也并非易事。那个街区会坐在哪里?它不能在targetBlock 内,因为一旦满足以上两个条件,显然targetBlock 内将不再处理任何消息。还要检查sourceBlock 的完成状态会带来很多低效率。
【问题讨论】:
-
你为什么需要知道这个?
-
因为一旦 targetBlock 中的所有项目完成处理,即使项目保留在 outQueue 中,我也会完成一个进程。一个原因是该过程的完成,另一个原因是延迟、吞吐量性能的测量。链接的下一个数据块可能需要更长的时间来处理 outQueue 中的所有剩余项目
-
为什么不等待源块的任务呢?您不需要附加一个块,只需在源块的
Completion属性上继续。
标签: c# concurrency task-parallel-library message-passing tpl-dataflow