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

时间:2015-07-14 23:32:08

标签: c# asynchronous task

换句话说,是

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 个答案:

答案 0 :(得分:9)

以下是一些差异:

  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会导致内存障碍,为什么会产生同步效果。
  9. 这有关系吗?通过此列表确定自己。

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

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