为何等待内部含已完成任务的async方法会产生意外输出?
异步代码执行顺序疑问
代码示例
public class Program { public static void Main() { Task task = ExampleTaskAsync(); Console.WriteLine("Method invoked"); task.Wait(); Console.WriteLine("main finished"); } static async Task ExampleTaskAsync() { Console.WriteLine("Started await"); await Task.FromResult(189); Console.WriteLine("During await"); await Task.Delay(867); Console.WriteLine("completed await"); } }
实际输出
Started await During await Method invoked completed await main finished
预期输出
Started await Method invoked During await completed await main finished
疑问:为何“During await”会出现在“Method invoked”之前?
原因解释
核心在于Task.FromResult(189)返回的是已经处于完成状态的Task。异步方法中,当await一个已完成的Task时,并不会挂起当前方法,而是直接同步执行await之后的代码,直到遇到下一个未完成的异步任务。
具体执行流程:
- 主线程调用
ExampleTaskAsync(),进入方法后立即打印Started await。 - 执行
await Task.FromResult(189):由于该Task已完成,无需等待,直接继续执行后续代码,打印During await。 - 执行
await Task.Delay(867):这个Task是未完成的(需要等待867毫秒),此时异步方法才会挂起,将一个未完成的Task返回给主线程。 - 主线程拿到返回的Task后,执行
Console.WriteLine("Method invoked")。 - 主线程调用
task.Wait()等待任务完成,867毫秒后异步方法恢复执行,打印completed await,任务完成。 - 主线程继续执行,打印
main finished。
正是因为第一个await的是已完成任务,导致During await在主线程打印Method invoked之前就被同步执行了。
内容的提问来源于stack exchange,提问作者Girish
相关产品推荐
相关产品推荐

