fra*_*tor 2 .net async-await asp.net-web-api
我正在检查一些使用 .NET 4.7.2 的 ASP.NET Web API 代码。
这是一个示例控制器和操作方法:
public class ThingController : System.Web.Http.ApiController
{
// ...
public async Task<IHttpActionResult> GetValue()
{
var value = await _db.GetValue().ConfigureAwait(false);
return Content(value);
}
}
Run Code Online (Sandbox Code Playgroud)
我读到,最佳实践是不在ConfigureAwait应用程序代码中使用,以便继续执行捕获的同步上下文,因为可能存在与捕获的上下文关联的所需状态。然而,一般来说,我们应该使用ConfigureAwait(false)这样的方法,这样我们就不会不必要地继续捕获的同步上下文。
所以我的想法是,我们不想ConfigureAwait(false)在此 Web API 代码中的任何位置进行调用。
然后我读到了有关死锁的内容,并且在使用 ASP.NET Core 时这并不重要(尽管我不是)。
我添加了一个断点并检查了SynchronizationContext.Current哪个是null.
ConfigureAwait(false)我可以安全地删除该项目的所有调用吗?如果不是,在什么情况下应该保留这些调用?
我读过,最佳实践是不在应用程序代码中使用ConfigureAwait,以便继续执行捕获的同步上下文,因为可能存在与捕获的上下文关联的所需状态。然而,一般来说,我们应该使用ConfigureAwait(false),这样我们就不会不必要地继续捕获的同步上下文。
我想说最好的做法是在库中使用ConfigureAwait(false),它可以在不同的上下文中使用。对于应用程序代码,ConfigureAwait(false)通常是不必要的。(出于性能原因,有一些高级情况ConfigureAwait(false)是必要的,但这种情况很少见)。
所以我的想法是,我们不想在此 Web API 代码中的任何位置调用ConfigureAwait(false)。
我同意。除了控制器方法之外,我通常会ConfigureAwait(false)在任何可以使用的地方使用,但您可以扩展“不使用ConfigureAwait(false)”规则以包括所有应用程序代码。
然后我读到了死锁......
死锁(如我的博客中所述)需要两个部分:
SynchronizationContext是单线程上下文。在您的代码中,没有同步异步,因此无论是否ConfigureAwait(false)使用都不可能出现死锁。
我添加了一个断点并检查了 SynchronizationContext.Current 为 null...HttpContext.Current 在调用之前为 null,实际上在进入该方法时。
实际上,这是非常有问题的。请阅读本文并确保您已完成在 ASP.NET 上使用代码的所有先决条件async。httpRuntime.targetFramework特别是,您必须对或进行适当的设置aspnet:UseTaskFriendlySynchronizationContext。
| 归档时间: |
|
| 查看次数: |
612 次 |
| 最近记录: |