【问题标题】:Task Parallelism - Task OnCompleted trigger on after all ContinueWith任务并行性 - 任务 OnCompleted 在所有 ContinueWith 之后触发
【发布时间】:2014-02-18 14:11:19
【问题描述】:

我在处理 task.GetAwaiter().OnCompleted(new Action) 时遇到问题

我有一个包含多个 ContinueWith 的主任务,但是当我返回主任务并在 OnCompleted 上添加一个委托时,它会在主任务处理后触发,而不是在所有 ContinueWith 之后触发

我的问题是,有没有办法知道所有 continue with 何时完成?

这是我当前的代码。

runningTask.Start();
    runningTask.GetAwaiter().OnCompleted(() =>
        {
             KeyValuePair<int, Func<bool>> validator = validationList.FirstOrDefault(x => x.Key == runningTask.Id);
             bool shouldContinue = validator.Value();
             if (shouldContinue)
             {
                  validationList.Remove(validator.Key);
                  PerformExecutionByQueue();
             }
         });

runningTask 是这样创建的

Task runningTask = new Task(delegate method);
Task secondTask = runningTask.ContinueWith(delegate method);

等等。 . .

【问题讨论】:

  • 请用您使用的语言标记它。
  • 完成,谢谢@RamanShah
  • 你想做什么?如果您想在任务完成时执行某些操作,只需在 proper 任务上使用 ContinueWith。 TaskAwaiter 主要由编译器使用,如果 OnComplete 总是在特定任务完成执行时触发,我不会感到惊讶,而不是在任务状态发生变化(例如 RanToCompletion、Canceled 或 Faulted)时触发。
  • @PanagiotisKanavos 我也尝试在 continuewith 上运行它,并使用 rantocompletion 的创建选项,但它也会在 mainTask 之后触发
  • 在哪个任务之后?如果你想让它在secondTask 之后运行,你应该调用secondTask.ContinueWith

标签: c# parallel-processing task


【解决方案1】:

将所有对ContinueWith 的调用的结果存储在某种集合中,然后在它们全部完成后使用Task.WhenAll 执行一些代码。

【讨论】:

  • 改变了这个答案,更加合乎逻辑并且在没有任何额外字段的情况下修复了实际问题
【解决方案2】:

当您调用ContinueWith 时,请尝试传入TaskContinuationOptions.AttachedToParent。这将告诉任务将延续视为父任务的一部分,并且在延续也完成之前不完成父任务。当然,这假设父任务还没有已经完成;如果有,当您调用ContinueWith() 时将内联执行延续。

【讨论】:

    【解决方案3】:

    ContinueWith 创建一个 secondTask,它只会在 runningTask 完成后运行。 secondTask 不会阻止 runningTask 完成,因此 OnCompleted 事件将在 runningTask 完成后立即触发。

    如果您想阻止 runningTasksecondTask 仍在运行时完成,请在 ContinueWith 中使用 TaskContinuationOptions.AttachToParent,例如:

    Task secondTask = runningTask.ContinueWith(delegate method,
                         TaskContinuationOptions.AttachToParent);
    

    AttachToParent 阻止其父任务完成,直到所有子任务完成。额外的好处是附加任务将在 Visual Studio 的任务视图中显示为父任务下的子任务

    【讨论】:

    • 这个我试过了,但是在runningTask之后还是会触发。
    • 在调用ContinueWith() 之前,您是否开始runningTask?如果是这样,则任务可能会在注册延续之前完成,在这种情况下,您的等待回调可能会在 secondTask 完成之前被调用。
    【解决方案4】:

    通过在类级别添加一个事件并在最后一个继续调用它来修复它。

    【讨论】:

      猜你喜欢
      • 2018-09-29
      • 2018-02-02
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      相关资源
      最近更新 更多