【问题标题】:Any way to wait for all tasks to be complete in ActionBlock?有什么方法可以等待 ActionBlock 中的所有任务完成?
【发布时间】:2015-10-22 06:06:53
【问题描述】:

首先,让我描述一下我正在编写的程序的流程。

GUI 中有一个对象列表,当用户单击一个对象时,将从磁盘读取对象数据并加载。这可能需要大约 3-4 秒。

假设用户不耐烦并在第一个对象仍在加载时单击另一个对象。程序将加载第二个对象,同时取消第一个对象的加载。

由于用户可能会在任何加载操作成功完成之前发送垃圾邮件,因此我实施了一个操作块来将所有加载操作排队。

所以我有一个这样的动作块:

this.loadObjectActionBlock = new ActionBlock<CaseObject>(
    c => this.LoadCaseData(CaseObject),
    new ExecutionDataflowBlockOptions()
    {
        MaxDegreeOfParallelism = 10,
    });

每次用户点击案例对象时,我都会调用:

this.loadObjectActionBlock.Post(CaseObject);

CaseObject 将由我这样定义的函数处理:

private void LoadCaseData(CaseObject caseObject)
    {
        caseObject.LoadCaseData();          
    }

我现在需要做的是,我需要等到所有 CaseObject 都加载完毕,然后才能继续我的代码。

我尝试通过调用来检测何时处理所有案例

if (this.loadObjectActionBlock.InputCount == 0)
{
    this.loadObjectActionBlock.Complete();
}

caseObject.LoadCaseData(); 之后,但是当加载动作发生得太快并且动作块被告知不再接受任何输入时,这会导致奇怪的结果。如果我理解正确,InputCount 属性只会查看队列中剩余的作业数。

所以我想做的是等待 ActionBlock 像:

await this.loadObjectActionBlock.Completion;

当队列中的所有内容都已完全处理完毕时。

我可能没有按预期使用 ActionBlock,所以如果有任何替代方案,请提出任何我可以阅读的内容。

TLDR:我想同时处理多个任务(由用户启动)并等待所有任务完成,然后再执行一个任务。

提前致谢:)

【问题讨论】:

    标签: c# task-parallel-library tpl-dataflow


    【解决方案1】:

    程序将加载第二个对象,同时取消第一个对象的加载。

    队列不是这种行为的合适解决方案,尤其是因为 TPL 块只能完成一次。

    如果您想实现此行为,只需确保在继续下一个操作之前观察到取消令牌:

    private static void ProcessCase(CaseObject caseObject, CancellationToken token)
    {
      caseObject.LoadCaseData();
      token.ThrowIfCancellationRequested();
      ... // Further processing goes here
    }
    

    从 UI 线程调用为:

    static CancellationTokenSource _cts;
    private static async Task ProcessCaseAsync(CaseObject caseObject)
    {
      if (_cts != null)
        _cts.Cancel();
      _cts = new CancellationTokenSource();
      await Task.Run(() => ProcessCase(caseObject, _cts.Token));
    }
    

    【讨论】:

    • 感谢您的回复。取消位现在不是问题,因为我正在取消 ProcessCase 方法之外的负载,并且我的操作块不需要取消令牌。我主要停留在我想等待所有排队的“ProcessCase”完成,然后再继续的部分。 Task.WhenAll 可能不适合我的情况,因为任务的数量没有定义,因为它们是由用户手动添加的。
    • @KurtisAung:我发布的解决方案不需要 TPL 数据流,也不需要等待所有操作完成,因为只有最近的操作会继续到 ... // Further processing 行。跨度>
    猜你喜欢
    • 2021-06-12
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多