使用async/await Task时控制台无输出的原因及正确实现方式
为什么控制台程序调用async方法不等待就没输出?附async/await正确用法
错误原因
第一段代码里,Main是同步方法,调用example1()后只是拿到了一个Task对象,但没有等待这个任务完成。控制台程序的主线程执行完Main方法后会直接终止整个进程,此时异步任务要么还没开始执行,要么刚执行到第一个await Task.Delay(1000)就被强制终止了,自然看不到任何输出。
这里要明确async方法的执行逻辑:调用时会同步执行到第一个await关键字,之后方法会立即返回一个Task,剩下的代码会在后台线程(由线程池管理)继续执行。但如果主线程不等它就结束,整个程序都终止了,后台任务也就跟着被干掉了。
正确实现方式
方式1:同步等待Task完成(你的第二段代码)
拿到Task对象后调用Wait()方法,强制主线程等待异步任务执行完毕再退出,适合简单的控制台测试场景:
using System; using System.Threading.Tasks; class HelloWorld { static void Main() { Task t = example1(); t.Wait(); // 等待异步任务完成 } static async Task DoWork() { Console.WriteLine( " Hello World! " ); for ( int i = 0 ; i < 3 ; i++ ) { Console.WriteLine( " Working..{0} " ,i); await Task.Delay( 1000 ); } } static async Task example1() { await DoWork(); Console.WriteLine( " First async Run End " ); } }
方式2:使用async Main(推荐,C#7.1+支持)
从C#7.1开始,控制台程序的Main方法可以标记为async Task,直接用await等待异步任务,这是更符合async/await设计理念的异步等待方式,避免了同步阻塞:
using System; using System.Threading.Tasks; class HelloWorld { static async Task Main() // 标记为async Task { await example1(); // 直接await异步任务 } static async Task DoWork() { Console.WriteLine( " Hello World! " ); for ( int i = 0 ; i < 3 ; i++ ) { Console.WriteLine( " Working..{0} " ,i); await Task.Delay( 1000 ); } } static async Task example1() { await DoWork(); Console.WriteLine( " First async Run End " ); } }
额外注意点
- 不要在WinForm、WPF这类有SynchronizationContext的环境里用
Task.Wait()或Task.Result,容易导致死锁,但控制台程序没有这个问题,因为默认没有SynchronizationContext。 - async方法尽量遵循"异步到底"的原则:如果一个方法调用了async方法,最好也把它改成async方法,用await等待,避免混合同步异步代码带来的问题。
内容的提问来源于stack exchange,提问作者harryLin
相关产品推荐
相关产品推荐

