【问题标题】:Multiple Task Continuation多任务继续
【发布时间】:2014-02-04 22:35:37
【问题描述】:

我想更清楚地理解这个场景:

考虑以下代码:

frmProgressAsync prog = new frmProgressAsync(true);
TaskWithProgress t = new TaskWithProgress("Smoothing CP", true);
t.Task = A.ShowMovingAverage(tension,t.Progress)
       .ContinueWith(prev =>
           {
               t.ProgressInformation.Report("Smoothing FG");
               B.ShowMovingAverage(tension, t.Progress);
           });
await prog.RunAsync(t);

我有两个任务要运行A.ShowMovingAverageB.ShowMovingAverage。两者都返回一个任务。

prog.RunAsync() 方法中,我有以下内容:

    public virtual Task RunAsync(TaskWithProgress task)
    {
        Show();
        TaskIsRunning();
        task.ContinueWith(Close(), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, this._Scheduler);
        return task.Task;
    }

所以我有三个任务,在前一个完成后依次运行。

现在我的问题是在某些情况下第一个任务几乎立即完成。当调用prog.RunAsync() 并将最终的延续附加到任务时,它会立即运行并关闭表单。

我可以看到我是否在最后一次 ContinueWith() 调用中中断,任务状态为 RanToCompletion,但我有点期待继续将其重置为进行中。

有人可以更清楚地解释这种行为吗?并提供一个潜在的解决方案,让所有任务(延续)在最终延续之前完成?

【问题讨论】:

    标签: c# task-parallel-library async-await continuations


    【解决方案1】:

    任务只完成一次。当您附加一个延续时,您正在创建一个新任务,该任务在前面的任务完成时开始。所以,我相信你看到的问题是RunAsync 附加了Close 延续,但没有对延续任务做任何事情;考虑task.Task = task.ContinueWith(Close(), ...)

    但是,我建议您使用await 而不是ContinueWith。我发现这通常会澄清代码并使其更易于理解。

    frmProgressAsync prog = new frmProgressAsync(true);
    TaskWithProgress t = new TaskWithProgress("Smoothing CP", true);
    t.Task = ShowMovingAveragesAsync(A, B, tension, t.Progress);
    await prog.RunAsync(t);
    
    private async Task ShowMovingAveragesAsync(TA A, TA B, TT tession, IProgress<string> progress)
    {
      progress.Report("Smoothing FG");
      await A.ShowMovingAverageAsync(tension, progress);
      progress.Report("Smoothing FG");
      await B.ShowMovingAverageAsync(tension, progress);
    }
    
    public virtual async Task RunAsync(TaskWithProgress task)
    {
      Show();
      TaskIsRunning();
      await task;
      Close();
    }
    

    【讨论】:

    • 感谢 Stephen,我注意到在这两种方法中,您都将返回类型定义为 Task,但实际上您并没有返回任何内容。这与您在博客中不鼓励的async void 不同吗?
    • 否; async Task 是定义没有返回值的 async 方法的正确方法。它不存在async void 引起的任何问题。
    • 非常感谢您的帮助
    猜你喜欢
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多