换句话说,就是
var task = SomeLongRunningOperationAsync();
task.Wait();
功能相同
SomeLongRunningOperation();
换句话说,就是
var task = SomeOtherLongRunningOperationAsync();
var result = task.Result;
功能相同
var result = SomeOtherLongRunningOperation();
根据 Task.Wait and Inlining ,如果正在等待 Wait
的任务已经开始执行,则 Wait
必须阻塞。然而,如果它还没有开始执行,Wait
可能能够将目标任务从它排队的调度程序中拉出来,并在当前线程上内联执行它。
这两种情况仅仅是决定任务将在哪个线程上运行的问题,如果您仍然在等待结果,这有关系吗?
如果在异步调用和 Wait()
之间没有执行任何操作,那么使用异步形式比使用同步形式有什么好处吗?
最佳答案
这里有一些区别:
- 计算可能在不同的线程上运行。如果此任务是基于 CPU 的并且可以内联,则它可能在同一线程上运行。这是不确定的。
- 如果没有发生内联,则在计算过程中将使用一个线程。这通常需要 1MB 的堆栈内存。
- 异常将包装在
AggregateException
中。异常堆栈会有所不同。 - The task version might deadlock if the computation posts to the current synchronization context.
- 如果线程池已满,如果要完成另一个任务必须安排另一个任务,则可能会死锁。
- 线程局部状态,例如
HttpContext.Current
(实际上不是线程局部但几乎是线程局部的),可能不同。 - 主线程的线程中止不会到达任务主体(内联情况除外)。我不确定等待本身是否会中止。
- 创建一个
Task
会引发一个内存屏障,它可以产生同步效果。
这重要吗?根据此列表自行决定。
这样做有好处吗?我想不出任何。如果您的计算使用异步 IO,等待将抵消异步 IO 带来的好处。一个异常(exception)是扇出 IO,例如并行发出 10 个 HTTP 请求并等待它们。这样一来,您就可以以一个线程为代价进行 10 次操作。
请注意,Wait
和 Result
在所有这些方面都是等效的。
关于c# - 在异步操作后立即调用 Task.Wait() 是否等同于同步运行相同的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33786357/