链接数据流块完成不起作用
Linked DataFlow block completion is not working
我有一个 BroadcastBlock
链接到 ActionBlock
。当我在 BroadcastBlock
和 ActionBlock
上依次调用 "complete" 时,它不起作用。而仅在 BroadCastBlock
上调用 "complete" 就可以了。
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()
并显示 "Finished"。如果我删除 _aciton.Complete()
,发布的值会正确显示,然后写入 "Finished"。
链接数据流块时,是否只调用根块的"Complete"?将 PropagateCompletion
设置为 true/false 无效。
解决方案
等待根块完成解决
public void Complete()
{
_input.Complete();
_input.Completion.Wait();
_action.Complete();
}
When dataflow blocks are linked, should we just call "Complete" of the root block only?
是的,这正是你应该做的。
如果您确实传播了 Completion
,那么您 不需要 需要自己完成 _actionBlock
- 它会在来自缓冲区进行处理。完成操作块后,它不会接受任何新消息,因此所描述的行为是预期且有效的。
我有一个 BroadcastBlock
链接到 ActionBlock
。当我在 BroadcastBlock
和 ActionBlock
上依次调用 "complete" 时,它不起作用。而仅在 BroadCastBlock
上调用 "complete" 就可以了。
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()
并显示 "Finished"。如果我删除 _aciton.Complete()
,发布的值会正确显示,然后写入 "Finished"。
链接数据流块时,是否只调用根块的"Complete"?将 PropagateCompletion
设置为 true/false 无效。
解决方案
等待根块完成解决
public void Complete()
{
_input.Complete();
_input.Completion.Wait();
_action.Complete();
}
When dataflow blocks are linked, should we just call "Complete" of the root block only?
是的,这正是你应该做的。
如果您确实传播了 Completion
,那么您 不需要 需要自己完成 _actionBlock
- 它会在来自缓冲区进行处理。完成操作块后,它不会接受任何新消息,因此所描述的行为是预期且有效的。