为什么我的异步方法在执行调用方方法的下一行之前完成?

Paa*_*pan 2 c# async-await

请考虑以下方法:

        public static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();

            // Begin timing.
            stopwatch.Start();

            Task task =  dosomething(stopwatch);
            Console.WriteLine("Waiting for async to finish {0}", stopwatch.Elapsed);
            task.Wait();
            Console.WriteLine("After wait {0}",stopwatch.Elapsed);


            // Stop timing.
            stopwatch.Stop();

            // Write result.
        }

        public static async Task dosomething(Stopwatch stopwatch)
        {
            Console.WriteLine("Started async", stopwatch.Elapsed);
            await dos();
            Console.WriteLine("Ended async", stopwatch.Elapsed);
        }

        public static async Task dos()  
        {
            Thread.Sleep(5000);
            Thread.Sleep(1000);

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我本来希望输出按以下顺序进行:

开始异步

等待异步完成

异步结束

等待之后

但是我得到以下输出

开始异步

异步结束

等待异步完成00:00:06.0990283

等待后00:00:06.0992659

我以为,当您等待方法完成时,控制权将返回给调用方。因此,应该在“结束异步”之前调用“等待异步完成”。

ger*_*rmi 8

Thread.Sleep不是异步的。因此,线程将被阻塞,您的代码将被同步执行。如果Thread.Sleep与交换await Task.Delay,您将获得预期的输出。

有关编译器应发出的警告(CS1998)的更多信息,请参见此问题。引用史蒂芬·克拉里(Stephen Cleary):

常见的async-newbie错误是假设async意味着“使此方法异步”。这通常与“异步”意味着“在后台线程上运行”的假设配对,但有时只是“魔术”的假设。

因此,警告明确指出该代码将同步运行。