链接数据流块完成不起作用

Linked DataFlow block completion is not working

我有一个 BroadcastBlock 链接到 ActionBlock。当我在 BroadcastBlockActionBlock 上依次调用 "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 - 它会在来自缓冲区进行处理。完成操作块后,它不会接受任何新消息,因此所描述的行为是预期且有效的。