为什么以下异步等待任务总是以相同的顺序完成?

时间:2017-07-08 14:35:04

标签: c# asynchronous async-await

这是一个关于这个问题的答案的问题:

How and When to use `async` and `await`

答案是:https://stackoverflow.com/a/31479502/1164004

要提出完整的问题,我也会复制粘贴答案:

  

这是一个快速的控制台程序,可以让跟踪者明白。 “TaskToDo”方法是您想要进行异步的长时间运行方法。使其运行Async由TestAsync方法完成。测试循环方法只运行“TaskToDo”任务并运行它们Async。您可以在结果中看到它们,因为它们在运行之间没有以相同的顺序完成 - 它们在完成时向控制台UI线程报告。简单,但我认为简单的例子比更多涉及的例子更好地展示了模式的核心:

    class Program
    {
        static void Main(string[] args)
        {
            TestLoops();
            Console.Read();
        }

        private static async void TestLoops()
        {
            for (int i = 0; i < 100; i++)
            {
                await TestAsync(i);
            }
        }

        private static Task TestAsync(int i)
        {
            return Task.Run(() => TaskToDo(i));
        }

        private async static void TaskToDo(int i)
        {
            await Task.Delay(10);
            Console.WriteLine(i);
        }
    }

现在就我而言:至于我的理解,await调用意味着如果任务结束,代码将继续。如果不是,它将返回到调用上下文,直到任务完成。如果是这种情况,那么为什么说在上面的程序中,循环的第一次迭代将返回到main方法的上下文直到任务完成,然后才会进行下一次迭代,这是不正确的。对于循环的所有迭代,是否执行for循环并以这种方式继续?如果它等待第一个结束,然后是第二个然后是第三个,依此类推,那么任务不会以自然顺序完成?

1 个答案:

答案 0 :(得分:0)

对于您的代码,执行将如下所示:

  1. 进入循环(迭代0)
  2. 致电TestAsync(0)
  3. 创建新任务(()=&gt; TaskToDo(0))
  4. 任务调用Task.Delay。
  5. 由于延迟任务未完成,控件将返回给调用者(lambda)。
  6. Lambda完成,它会触发您在步骤3中创建的任务。
  7. 此任务现已完成,循环继续,创建新任务。
  8. 然后await Task.Delay代码在延迟完成时开始工作,导致随机排序输出到控制台。