Task.Run无Wait()不执行求助:为何教程代码可运行我这里不行?
为什么你的Task代码没输出?这是控制台程序的线程生命周期坑
这是个非常典型的.NET控制台程序多线程入门问题,我来给你讲明白背后的原因:
核心问题:主线程提前终止了
控制台程序的主线程(也就是执行Main方法的线程)是整个程序的“命脉”——当Main方法执行完毕后,整个进程会直接终止,不管后台有没有还在运行的任务。
你用Task.Run()和Task.Factory.StartNew()启动的任务,默认都是在后台线程上运行的。当Main里的两行Task启动代码执行完后,主线程就走到了方法末尾,直接退出了,这时候后台线程还没来得及执行Print()里的循环(或者刚执行了几个就被强制终止),所以你看不到任何输出。
为什么加Wait()就正常了?
Wait()方法的作用是阻塞当前线程(这里就是主线程),直到对应的Task完全执行完毕。加上Wait()后,主线程不会立刻退出,会一直等Print()把100个数字都打印完,自然就能看到输出了。
其他可行的解决方案
除了单个Task调用Wait(),还有几种更灵活的方式:
1. 等待多个任务全部完成
如果你启动了多个Task,可以用Task.WhenAll()一次性等待所有任务结束,比一个个调用Wait()更优雅:
class Program { static void Main(string[] args) { var t1 = Task.Run(() => Print()); var t2 = Task.Factory.StartNew(() => Print()); // 等待两个任务都执行完成 Task.WhenAll(t1, t2).Wait(); } private static void Print() { for (int i = 0; i < 100; i++) { Console.WriteLine(i); } } }
2. 使用异步Main方法(推荐)
如果你用的是C# 7.1及以上版本,可以把Main改成async Task类型,用await来等待任务,这种方式不会阻塞主线程,是更现代的写法:
class Program { static async Task Main(string[] args) { var t1 = Task.Run(() => Print()); var t2 = Task.Factory.StartNew(() => Print()); // await会等待所有任务完成,且不会阻塞线程 await Task.WhenAll(t1, t2); } private static void Print() { for (int i = 0; i < 100; i++) { Console.WriteLine(i); } } }
3. 让主线程主动等待(仅调试用)
如果只是临时调试,也可以在Main末尾加Console.ReadLine(),让主线程等待用户输入,给后台任务足够的执行时间:
class Program { static void Main(string[] args) { Task.Run(() => Print()); Task.Factory.StartNew(() => Print()); // 主线程等待用户输入,不会立刻退出 Console.ReadLine(); } private static void Print() { for (int i = 0; i < 100; i++) { Console.WriteLine(i); } } }
不过这种方法只适合调试场景,正式代码里不建议用,因为需要用户手动输入才能退出程序。
内容的提问来源于stack exchange,提问作者Richard77
相关产品推荐
相关产品推荐

