为什么调用OnlyOnCanceled延续? [英] Why does the OnlyOnCanceled continuation get called?

查看:52
本文介绍了为什么调用OnlyOnCanceled延续?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When calling await RunAsync(); on the below code, I would expect the continuation with TaskContinuationOptions.OnlyRanToCompletion continuation to run, however the OnlyOnCanceled continuation gets called (yielding the debug output "Task canceled").

为什么?

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

}

推荐答案

您将续订绑定错误.

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

Instead of adding three continuations to the "main" task, you're adding a continuation to a continuation to a continuation. When the main tasks finishes without error, the OnlyOnFaulted continuation gets cancelled, which triggers the OnlyOnCanceled continuation you incorrectly wired to the OnlyOnFaulted continuation instead of the main task. And then the best part - this means that the second continuation finished correctly, and since you wired your last continuation on the second continuation, the final continuation runs as well, so the full output is "Task canceled. Task completed." :)

不过,您所期望的正确输出并不明显.为什么首先要使用延续? await 为您提供的服务比手动完成的要好得多.混合 await ContinueWith 很少是一个好主意:)您是否要尝试 await 主要任务(抛出异常时失败)?还是延续之一?还是仅仅是 OnlyOnRanToCompletion 的延续(这就是您现在正在做的事情,并且它永远不会以您期望的方式工作)?如果这种延续没有机会继续下去怎么办?

It's not obvious what you're expecting to be the correct output, though. Why are you using continuations in the first place? await handles that for you much more nicely than you can ever do manually. Mixing await and ContinueWith is rarely a good idea :) Are you trying to await the main task (failing when an exception is thrown)? Or one of the continuations? Or just the OnlyOnRanToCompletion continuation (that's what you're doing right now, and it's never going to work the way you expect it to work)? What if that continuation never gets a chance to run?

这篇关于为什么调用OnlyOnCanceled延续?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆