c# - 在异步操作后立即调用 Task.Wait() 是否等同于同步运行相同的操作?

标签 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. 计算可能在不同的线程上运行。如果此任务是基于 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 带来的好处。一个异常(exception)是扇出 IO,例如并行发出 10 个 HTTP 请求并等待它们。这样一来,您就可以以一个线程为代价进行 10 次操作。

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

关于c# - 在异步操作后立即调用 Task.Wait() 是否等同于同步运行相同的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33786357/

相关文章:

c# - Visual Studio 2012 : List of all Methods in class

c# - 是否可以使用反射从通用实体访问属性(按名称)?

c# - java脚本到C#的回调,c#和java脚本之间的异步编程

python - 在单个请求中使用 grequests

java - msbuild 中 java jar 的对应项是什么?

c# - 在 C# 的 string[] 数组中插入字符串

c# - 通过 TCP 接收不完整/错误的字符串

javascript - 如何从异步调用返回响应?

c# - 取消任务时不执行延续任务

Python如何准确安排一次性任务