【发布时间】:2020-02-29 14:16:24
【问题描述】:
如果我有以下代码:
public async Task<SomeObject> ActionMethodAsync()
{
return await someAsyncMethod();
}
我应该把它改成:
public SomeObject ActionMethod()
{
return someAsyncMethod().GetAwaiter().GetResult();
}
我不确定一旦控制权返回给ActionMethodAsync 的调用者,究竟会发生什么以及是否实现了任何有益的结果。
会不会产生和following编译器编译的代码类似的结果,或者是IIS给的一个线程池线程,如果我们走await路线就不会被阻塞?我觉得我们仍然会使用单个线程,无论我们选择继续使用哪个选项。 (无需切换线程上下文和异步状态机的额外成本。)
【问题讨论】:
-
第一个不阻塞,第二个阻塞。它们是完全不同的,如果你能提供帮助,你不想同步等待
async方法。您可以在不改变语义的情况下将其更改为return someAsyncMethod()(没有async,但保持返回类型相同)。 -
@JeroenMostert 不会将未完成的任务返回给执行该操作的用户吗?
-
@SpiritBob:当然——这就是重点。 ASP.NET 框架是最终等待您的任务(或者更确切地说是调度延续,效率更高)的框架,而不是某些最终用户。
-
当然,虽然它实际上是为了在您的控制器中允许完整的
async/await。直接返回另一个async方法的结果的情况有点不寻常。为了一致性起见,大多数人仍然会将方法写成async,然后再写return await,以防你以后需要使事情变得更复杂,即使这与直接返回结果完成相同的事情并且它有一点点更多开销(因为编译器仍然在后台生成一个完整的异步状态机)。 -
ASP.NET Core 特别是完全异步的——最新版本实际上是contain code that will produce errors,当它们检测到同步 I/O 时,因为已发现这会导致线程池饥饿。这就是他们多么希望你一路走
async。 ASP.NET“仅仅”添加了async支持,但即使那是7 年前的事了(查看文章上的日期)。让所有请求代码异步运行(将其与线程解耦)对可扩展性有很大好处。
标签: c# asp.net multithreading asynchronous async-await