1

在代码流可以继续之前,我需要取消一个待处理的任务并等待它的终止。通常,我这样做:

if (this.task != null)
{
    this.taskCancellationTokenSource.Cancel();
    try
    {
        await this.task;
        // I don't need to know the result, just log it
        Debug.Print(this.task.Status.ToString());
    }
    catch (Exception e)
    {
        // I don't need to know the result, just log it
        Debug.Print(e.ToString());
    }
}

我刚刚意识到我可以在没有以下情况下做同样的事情try/catch

if (this.task != null)
{
    this.taskCancellationTokenSource.Cancel();
    await this.task.ContinueWith(
        // I don't need to know the result, just log it
        (t) => Debug.Print(((object)t.Exception ?? (object)t.Status).ToString()), 
        TaskContinuationOptions.ExecuteSynchronously)
}

我错过了我应该坚持第一种方法的任何理由吗?

4

1 回答 1

2

我错过了我应该坚持第一种方法的任何理由吗?

两个原因,在我脑海中浮现:

  1. ContinueWith默认情况下将使用当前调度程序,这可能会导致并发问题或令人惊讶的行为。
  2. 当您读取属性时,前面的任务(t在您的示例中)将包含任何异常。AggregateExceptionTask.Exception

我建议使用await而不是ContinueWith因为它在这两种情况下都有更合理的行为。await将捕获当前上下文并使用它来安排继续,并且await不会将异常包装在AggregateException.

如果您确实使用ContinueWith,那么您应该始终明确指定 aTaskScheduler继续运行。

于 2013-09-25T12:24:27.530 回答