在异步操作后立即调用Task.Wait(),相当于同步运行相同的操作

本文关键字:同步 相当于 运行 操作 异步操作 调用 Wait Task | 更新日期: 2023-09-27 18:02:47

换句话说,是

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

功能相同
SomeLongRunningOperation();

换句话说,是

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

功能相同
var result = SomeOtherLongRunningOperation();

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

这两种情况是否仅仅是决定任务将在哪个线程上运行的问题,如果您正在等待结果,这是否重要?

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

在异步操作后立即调用Task.Wait(),相当于同步运行相同的操作

以下是一些不同之处:

    计算可能在不同的线程上运行。如果此任务基于cpu并且可以内联,则它可能在同一线程上运行。这是不确定的。
  1. 如果没有发生内联,则在计算期间将使用另一个线程。这通常需要1MB堆栈内存。
  2. 异常将被包装在AggregateException中。异常堆栈将会不同。
  3. 如果计算提交到当前同步上下文,任务版本可能会死锁
  4. 如果线程池已满,如果要完成任务必须安排另一个任务,则可能会死锁。
  5. 线程本地状态,如HttpContext.Current(实际上不是线程本地,但几乎),可能是不同的。主线程的线程中止将无法到达任务体(内联的情况除外)。我不确定等待本身是否会被终止。
  6. 创建Task会产生内存屏障,从而产生同步效果。

这有关系吗?根据这个列表你自己决定。

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

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