2
我有一个BroadcastBlock
链接到ActionBlock
。当我在BroadcastBlock
和ActionBlock
上顺序呼叫“完成”时,它不起作用。而仅仅在BroadCastBlock
上打电话“完成”正在工作。链接的DataFlow块完成不起作用
public class ActionTester
{
private readonly ActionBlock<int> _action;
private readonly BroadcastBlock<int> _input;
public ActionTester()
{
_input = new BroadcastBlock<int>(null);
_action = new ActionBlock<int>(i => Process(i));
_input.LinkTo(_action, new DataflowLinkOptions { PropagateCompletion = true });
}
public void Post(int i) => _input.Post(i);
public async Task Process(int i)
{
await Task.Delay(2000);
Console.WriteLine(i);
}
public void Complete()
{
_input.Complete();
_action.Complete(); // When this is removed, program is working as expected
}
public Task Completion => _action.Completion;
}
测试代码是
static void Main(string[] args)
{
var actor = new ActionTester();
actor.Post(5);
actor.Post(7);
actor.Complete();
actor.Completion.Wait();
Console.WriteLine("Finished");
Console.Read();
}
当_action.Complete()
存在(注释行),码移动经过actor.Completion.wait()
和 “完成” 是越来越显示。如果我删除_aciton.Complete()
,则显示的值将正确显示,然后写入“完成”。
当数据流块被链接时,我们是否应该只调用根块的“完成”?将PropagateCompletion
设置为true/false不起作用。
解决方案
通过等待根块完成
public void Complete()
{
_input.Complete();
_input.Completion.Wait();
_action.Complete();
}
当“PropogateCompletion”设置为false时,我们不应该在所有链接的块上调用complete吗?在我的例子中,即使我将PropagateCompletion设置为false,如果我在链接块上完成另一个调用,它也不起作用。 – Saravanan
如果您在**之前完成第二个块**,则从第一个到第二个发送所有消息,第二个将放弃所有这些消息。所以,如果你不传播完成,你需要自己处理它。 – VMAtm