为什么ContinueWith返回的第二个Task不调用Wait()也能正常执行?
问题解答
第一个Task不调用Wait()就无输出的原因
- .NET 中默认创建的普通 Task 绑定的都是后台线程,进程退出时会直接终止所有后台线程,不会等待它们执行完毕
- 控制台程序的 Main 方法运行在唯一的前台线程上,如果你不调用
MyTask1.Wait(),主线程会立刻走完 Main 里的所有逻辑触发进程退出,MyMethod1还没来得及在后台线程执行就被销毁了,自然没有输出。
第二个Task不需要调用Wait()也能执行的原因
核心原因是你调用ContinueWith的时候,MyTask1已经完全执行完成了:
- 你已经提前调用了
MyTask1.Wait(),这行代码会阻塞主线程直到MyTask1执行结束,才会继续往下走 ContinueWith的默认行为是:如果调用时前置任务已经处于完成状态,会直接在当前调用ContinueWith的线程(也就是主线程)上同步执行延续委托,根本不需要调度到后台线程池- 也就是说
MyMethod2在你赋值MyTask2的那一刻就已经在主线程上跑完了,当然不需要额外调用Wait()等待。
如果你想验证这个逻辑,可以做两个小测试:
- 保留
MyTask1.Wait(),但给ContinueWith加上参数TaskContinuationOptions.RunContinuationsAsynchronously强制延续任务异步执行,你会发现大概率不会输出2,因为异步调度的后台线程还没执行,主线程就走完触发进程退出了 - 注释掉
MyTask1.Wait(),但在MyTask1.Start()之后加一行Thread.Sleep(100)保证MyTask1先执行完,再调用ContinueWith,你会发现哪怕不调用MyTask2.Wait()也会输出2
内容的提问来源于stack exchange,提问作者user17246701
相关产品推荐
相关产品推荐

