在等同于 运行 同步操作的异步操作之后立即调用 Task.Wait() 吗?

Is calling Task.Wait() immediately after an asynchronous operation equivalent to running the same operation synchronously?

换句话说就是

var task = SomeLongRunningOperationAsync();
task.Wait();

在功能上与

相同
SomeLongRunningOperation();

换句话说,就是

var task = SomeOtherLongRunningOperationAsync();
var result = task.Result;

功能上与

相同
var result = SomeOtherLongRunningOperation();

根据Task.Wait and Inlining,如果Wait上的任务已经开始执行,Wait必须阻塞。但是,如果它还没有开始执行,Wait 可能能够将目标任务从它排队的调度程序中拉出来,并在当前线程上内联执行它。

这两种情况仅仅是决定任务将 运行 放在哪个线程上的问题,如果您仍然在等待结果,这有关系吗?

如果在异步调用和 Wait() 之间没有任何执行,那么使用异步形式比使用同步形式有什么好处吗?

这里有一些区别:

  1. 计算可能 运行 在不同的线程上。如果此任务基于 CPU 并且可以内联,则它可能 运行 在同一线程上。这是不确定的。
  2. 如果没有发生内联,则在计算期间将使用一个线程。这通常需要 1MB 的堆栈内存。
  3. 例外情况将包含在 AggregateException 中。异常堆栈会有所不同。
  4. The task version might deadlock if the computation posts to the current synchronization context.
  5. 如果线程池已满,如果必须安排另一个任务才能完成任务,则可能会死锁。
  6. 线程局部状态,比如HttpContext.Current(实际上不是线程局部但差不多),可能不同
  7. 主线程的线程中止不会到达任务体(内联情况除外)。我不确定等待本身是否会被中止。
  8. 创建一个 Task 会引发一个内存屏障,它可以产生同步效果。

这重要吗?根据此列表自行决定。

这样做有什么好处吗?我想不出任何。如果您的计算使用异步 IO,等待将抵消异步 IO 带来的好处。一个例外是扇出 IO,例如并行发出 10 个 HTTP 请求并等待它们。这样一来,您就可以以一个线程为代价进行 10 次操作。

请注意,WaitResult 在所有这些方面都是等效的。