Task.ContinueWith()父任务不等待子任务完成

时间:2014-12-29 12:34:28

标签: c# .net multithreading c#-4.0 task-parallel-library

由于我在嵌套任务的上下文中理解Task,我真的不明白 - 为什么第二次打印之前的第三次打印?

即使我使用了Task.WaitAll(t),它也会在 2nd 行之前打印 3rd 行。

代码:

public static void Main()
        {

            Task t = new Task(
                () =>
                {
                    Thread.Sleep(2000);
                    Console.WriteLine("1st print...");
                });
           t.ContinueWith(
                x =>
                {
                    Thread.Sleep(2000);
                    Console.WriteLine("2nd print...");
                },
                TaskContinuationOptions.OnlyOnRanToCompletion);

            t.Start();
            Task.WaitAll(t);

            Console.WriteLine("3rd print...");
            Console.Read();

}

输出:

enter image description here

3 个答案:

答案 0 :(得分:7)

您还需要等待继续:

Task t2 = t.ContinueWith( /* .. */ );
Task.WaitAll(new [] { t, t2 } );

答案 1 :(得分:3)

您只等待t,而不是等待它继续。这就是为什么延续将在未来某个时间运行的原因。如果它不是Console.Read,它可能永远不会在进程退出之前运行。

Task.WaitAll(t)相当于t.Wait()(您应该使用它,因为它更惯用)。

让它等待所有延续(可能是递归)将导致不直观的行为并具有非局部效果。程序的远程部分可能会影响您的代码。

答案 2 :(得分:0)

你假设它应该等待子任务,但没有基础做出这样的假设。来自MSDN:

  

Task.WaitAll:等待所有提供的Task对象完成   执行。

它完全符合它的说法。 ContinueWith不会改变原始任务的长度,也不会变得更长。它只是在它之后执行。