Multiple Task Continuation

丶灬走出姿态 提交于 2020-01-05 08:38:24

问题


I would like to understand this scenario a little clearer:

Consider the following code:

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);

I have two tasks I wish to run A.ShowMovingAverage and B.ShowMovingAverage. Both return a Task.

In the prog.RunAsync() method, I have the following:

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

So effectively I have three tasks, to run in turn one after the previous is complete.

Now my issue is in some cases the first task completes virtually immediately. When the call to prog.RunAsync() is made, and the final continuation is appended to the task, it immediately runs, closing the form.

I can see if I break on the last ContinueWith() call, the task status is RanToCompletion, but I am kind of expecting the continuation to reset this back to in progress.

Could someone please explain this behavior a little more cleanly? And provide a potential solution so that all the tasks (continuations) complete before the final continuation?


回答1:


Tasks only complete one time. When you attach a continuation, you are creating a new task that starts when the antecedent task completes. So, I believe the problem you're seeing is that RunAsync is attaching the Close continuation but not doing anything with the continuation task; consider task.Task = task.ContinueWith(Close(), ...).

However, I recommend that you use await instead of ContinueWith. I find that usually clarifies the code and makes it easier to understand.

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();
}


来源:https://stackoverflow.com/questions/21154692/multiple-task-continuation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!