.NET 4.5中Main线程调用async void方法无法等待问题求助
解决.NET 4.5控制台程序主线程等待async方法的问题
你的问题核心在于**async static void类型的方法并不适合在控制台主线程中用来做需要等待的异步操作**——这种返回类型主要是为UI事件处理器设计的,控制台的主线程不会跟踪它的执行状态,所以调用后会直接继续执行后续代码,直到Main方法结束,程序自然就关闭了。
下面给你两种可行的解决方案,优先推荐第一种:
方案一:修改异步方法返回类型为Task并阻塞主线程等待
这是最规范的做法,把WaitMy的返回类型从void改成Task,然后在Main方法里通过.GetAwaiter().GetResult()来等待它执行完成(因为.NET 4.5的Main方法还不支持直接标记为async)。
修改后的完整代码:
static void Main(string[] args) { // any code here... Console.WriteLine("Discovery started"); // 阻塞主线程,直到异步方法执行完成 WaitMy().GetAwaiter().GetResult(); } private async static Task WaitMy() { // 这里不需要嵌套Task.Run,Task.Delay本身就是异步操作 await Task.Delay(30 * 1000); }
额外说明:
你原来代码里的await Task.Run(async () => await Task.Delay(30 * 1000))是多余的——Task.Delay本身就会返回一个可等待的Task,不需要再用Task.Run包装,这样只会额外创建线程,完全没必要。
方案二:使用同步原语(不推荐,仅作补充)
如果因为某些原因不能修改WaitMy的返回类型,可以用ManualResetEvent来让主线程等待异步方法执行完毕:
static void Main(string[] args) { Console.WriteLine("Discovery started"); var resetEvent = new ManualResetEvent(false); WaitMy(resetEvent); // 等待事件被触发 resetEvent.WaitOne(); } private async static void WaitMy(ManualResetEvent resetEvent) { await Task.Delay(30 * 1000); // 异步操作完成后触发事件 resetEvent.Set(); }
不过这种方法不够优雅,而且async void方法如果抛出异常,很难捕获和处理,所以优先选择方案一。
内容的提问来源于stack exchange,提问作者jenokizm
相关产品推荐
相关产品推荐

