繁体   English   中英

有什么方法可以等待ActionBlock中的所有任务完成吗?

[英]Any way to wait for all tasks to be complete in ActionBlock?

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

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

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

由于用户可以在垃圾邮件加载操作无法成功完成之前对其进行垃圾邮件处理,因此我实现了一个动作块来对所有加载操作进行排队。

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

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

每次用户单击Case对象时,我都会调用:

this.loadObjectActionBlock.Post(CaseObject);

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

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

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

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

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

caseObject.LoadCaseData(); 但这会导致奇怪的结果,即加载操作发生得太快并且告诉操作块不要接受更多输入。 如果我理解正确, InputCount属性仅查看队列中剩余的作业数。

所以我想做的就是等待ActionBlock之类的:

await this.loadObjectActionBlock.Completion;

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

我可能未按预期使用ActionBlock,因此,如果对此有任何选择,请提出我可以阅读的任何内容。

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

提前致谢 :)

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

队列不是解决此问题的适当方法,特别是因为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));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM