这三个任务延续之间有什么区别?



我有两种情况,但我不明白为什么事情会这样发生:

    static void Main(string[] args)
    {
        Console.WriteLine("***Starting T1");
        //run two tasks sequentially
        Task t = FirstTask().ContinueWith(_ => SecondTask(), TaskContinuationOptions.OnlyOnRanToCompletion);
        //register succeded and faulted continuations
        t.ContinueWith(_ => Completion(), TaskContinuationOptions.OnlyOnRanToCompletion);
        t.ContinueWith(_ => Faulted(), TaskContinuationOptions.OnlyOnFaulted);
        Console.ReadLine();
        Console.WriteLine("***Starting T2");
        Task t2 = FirstTask().ContinueWith(_ => FaultTask(), TaskContinuationOptions.OnlyOnRanToCompletion);
        t2.ContinueWith(_ => Completion(), TaskContinuationOptions.OnlyOnRanToCompletion);
        t2.ContinueWith(_ => Faulted(), TaskContinuationOptions.OnlyOnFaulted);
        Console.ReadLine();
        Console.WriteLine("***Starting T3");
        Task t3 = FirstTask().ContinueWith(ant => ant.ContinueWith(_ => FaultTask(), TaskContinuationOptions.OnlyOnRanToCompletion));
        t3.ContinueWith(_ => Completion(), TaskContinuationOptions.OnlyOnRanToCompletion);
        t3.ContinueWith(_ => Faulted(), TaskContinuationOptions.OnlyOnFaulted);
        Console.ReadLine();
    }
    private static Task FirstTask()
    {
        return Task.Run(() =>
        {
            Console.WriteLine("Task 1");
            Thread.Sleep(1000);
        });
    }
    private static Task SecondTask()
    {
        return Task.Run(() =>
        {
            Console.WriteLine("Task 2");
            Thread.Sleep(1000);
        });
    }
    private static Task FaultTask()
    {
        return Task.Run(() =>
        {
            Console.WriteLine("Throw...");
            Thread.Sleep(1000);
            throw new ArgumentException();
        });
    }
    private static void Completion()
    {
        Console.WriteLine("Complete");
    }
    private static void Faulted()
    {
        Console.WriteLine("Faulted");
    }

在情况 1 中,事情按预期运行。但是,如果删除了 FirstTask() 中的Sleep(),则无法保证任务按顺序运行。

在案例 2 中,不运行Faulted()处理程序。我希望发生这种情况,因为存在未处理的异常。

在情况 3 中,在运行Complete()处理程序后引发异常。我很困惑为什么会发生这种排序。

基本上,我希望能够链接任意数量的任务,并在前一个任务完成后按顺序运行。创建链后,我将显示一个等待表单并注册OnlyOnRanToCompletionOnlyOnCancelledOnlyOnFaulted的延续到最终任务(阅读:全部完成后)以关闭表单 - 显示成功或错误。

这是 MSDN 所指的那些不可用于多任务延续的选项吗?

tt2上的返回类型Task<Task>不仅仅是一个任务。 T3 是一个Task<Task<Task>>。 要获得所需的行为,您应该能够解开任务,这将为您提供代表整个操作的任务(有关详细信息,请阅读文档):

Console.WriteLine("***Starting T1");
//run two tasks sequentially
Task<Task> t = FirstTask().ContinueWith(_ => SecondTask(), TaskContinuationOptions.OnlyOnRanToCompletion);
//register succeded and faulted continuations
t.Unwrap().ContinueWith(_ => Completion(), TaskContinuationOptions.OnlyOnRanToCompletion);
t.Unwrap().ContinueWith(_ => Faulted(), TaskContinuationOptions.OnlyOnFaulted);
Console.ReadLine();
Console.WriteLine("***Starting T2");
Task<Task> t2 = FirstTask().ContinueWith(_ => FaultTask(), TaskContinuationOptions.OnlyOnRanToCompletion);
t2.Unwrap().ContinueWith(_ => Completion(), TaskContinuationOptions.OnlyOnRanToCompletion);
t2.Unwrap().ContinueWith(_ => Faulted(), TaskContinuationOptions.OnlyOnFaulted);
Console.ReadLine();

我建议尽可能考虑使用 async/await 模式,因为它使处理此类任务变得更加容易。

最新更新