为什么要调用OnlyOnCanceled延续?

时间:2016-06-01 11:17:49

标签: c# async-await task continuations cancellation

在下面的代码上调用await RunAsync();时,我希望继续TaskContinuationOptions.OnlyRanToCompletion继续运行,但OnlyOnCanceled延续被调用(产生调试输出"任务取消&#34)。

为什么?

private static async Task RunAsync()
{
    try
    {
        await Task.Run(() => DoWork())
            .ContinueWith(
                (t) =>
                {
                    if (t?.Exception != null)
                    {
                        throw t.Exception;
                    }
                }, TaskContinuationOptions.OnlyOnFaulted
            ).ContinueWith(
                (t) =>
                {
                    Debug.WriteLine("Task canceled.");
                }, TaskContinuationOptions.OnlyOnCanceled
            ).ContinueWith(
                (t) =>
                {
                    Debug.WriteLine("Task completed.");
                }, TaskContinuationOptions.OnlyOnRanToCompletion);

    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
}

private static void DoWork()
{
    Thread.Sleep(1000);

}

1 个答案:

答案 0 :(得分:4)

你的继承错误。

不是向“主”任务添加三个延续,而是在延续中添加延续。当主要任务完成且没有错误时,OnlyOnFaulted延续会被取消,这会触发OnlyOnCanceled继续错误连接到OnlyOnFaulted延续而不是主任务。然后是最好的部分 - 这意味着第二个延续正确完成,并且由于您在第二个延续上连接了最后一个延续,最后的延续也运行,因此完整输出是“任务取消。任务完成”。 :)

但是,你期望成为正确的输出并不明显。你为什么一开始就使用延续? await比你手动处理的更好。混合awaitContinueWith很少是一个好主意:)您是否尝试await主要任务(抛出异常时失败)?还是其中一个延续?或者只是OnlyOnRanToCompletion延续(这就是你现在正在做的事情,它永远不会像你期望的那样工作)?如果那个延续永远不会有机会运行怎么办?