为何直接调用异步方法失效,用Task.Factory.StartNew执行却可行?
两种Task启动方式的差异解析
核心差异在于同步阻塞代码的执行线程,关键看你的ReadConsoleInput方法里的Console.ReadKey(true)——这是个同步阻塞调用,会卡住当前执行它的线程。
直接调用ReadConsoleInput的情况
当你写var consoleReadTask = ReadConsoleInput(...)时:
- async方法的执行规则是:调用后会同步执行到第一个
await语句之前的所有代码。也就是说,Console.ReadKey(true)会直接在你调用这个方法的线程(通常是控制台程序的主线程)上执行,直接把主线程卡住。主线程被阻塞等待用户输入,程序自然看起来挂起,没法处理其他任务。
使用Task.Factory.StartNew的情况
当你用Task.Factory.StartNew(async () => await ReadConsoleInput(...))时:
Task.Factory.StartNew会把传入的async lambda委托丢到线程池线程上去执行。这时候Console.ReadKey(true)阻塞的是线程池线程,而不是主线程。主线程可以继续处理其他任务,程序也就不会挂起,能正常运行。
额外提一句:你用Task.Factory.StartNew配合async lambda其实会返回Task<Task>(嵌套任务),更规范的写法是用Task.Run(async () => await ReadConsoleInput(...)),它会自动帮你解开嵌套的Task,效果和你当前的写法一致,但更简洁清晰。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

