DataflowBlock.Complete() 应该阻止块产生更多消息,排队的项目会发生什么

本文关键字:排队 消息 项目 什么 DataflowBlock Complete | 更新日期: 2023-09-27 18:00:39

.Complete()的文档如下:

IDataflowBlock发出信号,表明它不应该接受或生产 任何更多消息,也不会再使用任何推迟的消息。

因此,假设我有一个BatchedJoinBlock,我想在其源块完成时完成,但我无法传播,因为链接位于谓词上:

block1.LinkTo(block2.Target1, predicate);
block1.LinkTo(block2.Target2, !predicate);
await block1.Completion;
block2.Complete();

因此,根据文档,最后一行将阻止block2生成新消息,但问题是block1block2接受所有消息后立即完成,但这些接受的消息可能尚未处理,那么如果block2无法生成新消息,它们会发生什么?

也许我误解了生产消息

DataflowBlock.Complete() 应该阻止块产生更多消息,排队的项目会发生什么

Complete表示块将停止接受更多消息,但它处理其InputQueue中的消息,即使这将导致在管道中向前发送消息(而不是当块因异常而出错时(。

你可以从这个简单的例子中看到这一点:

var transformBlock = new TransformBlock<int, int>(async _ =>
{
    await Task.Delay(100);
    return _;
});
var actionBlock = new ActionBlock<int>(_ => Console.WriteLine(_));
transformBlock.LinkTo(actionBlock);
for (int i = 0; i < 1000; i++)
{
    await transformBlock.SendAsync(i);
}
transformBlock.Complete();
Console.WriteLine("complete");
await transformBlock.Completion;
Console.WriteLine("completed");

complete将立即写入,但TransformBlock将继续处理消息并慢慢将它们移动到下一个ActionBlock


我也不完全确定"再产生消息">的实际含义。我假设它与产生消息的块有关,而不是与处理传入消息的块有关,尽管我想不出一个。