[英]Deadlock when calling an async method inside a non async action
我们有一个 web 应用程序,它由我们的 UI 使用的 Web API 组成。 web 应用程序安装在不同的服务器上(在我们的客户安装之前进行测试)。
在一台服务器上,我们通过以下端点获得了死锁:
[HttpGet, Route(Order = 1)]
public IHttpActionResult GetUserDetails(long userKey)
{
var userService = ResolveService<IUserService>();
var nameService = ResolveService<INameService >();
LoggInfo("Start userService.Get()"); //logged in logs
var result = userService.Get(userKey);
this.LoggInfo($"End userService.Get() with id = "{result.Id}); // logged in logs
try
{
LoggInfo($"Start nameService.Get()"); // logged in logs
result.Name = nameService.Get(result.Namekey).Result?.Name;
LoggInfo($"End nameService.Get()"); // not logged in logs
}
catch(Exception ex)
{
LogError("An error occured in NameService"); // not logged in logs
}
return Ok(result);
}
nameService.Get(id)
是一个async
方法:
public async Task<NameDTO> GetAsync(long key)
{
LogInfo("start NameService.Get()"); // not logged in logs
var query = GetQuery();
var name = await query.Select(MapName())
.FirstOrDefaultAsync(n => n.Key == key);
return name;
}
当我删除异步签名时,一切都按预期工作,根据这篇文章,出现死锁是正常的。
你能解释一下为什么这在其他服务器上有效吗?
在此先感谢您的帮助
你能解释一下为什么这在其他服务器上有效吗?
为了使死锁发生,有三个必要的部分:
await
(没有ConfigureAwait(false)
)。async
方法完成。 所有服务器也有这个。 最有可能的是,行为上的差异是由于第二部分:异步操作的await
。 await
首先检查它的 awaitable(例如,传递给它的Task
),如果该 awaitable 完成,那么它会继续同步执行async
方法。
具体来说,如果从GetAsync
返回的Task<NameDTO>
在调用代码命中.Result
之前完成,就会发生这种情况。 这必须非常快,但这可能取决于缓存、网络跃点的速度、加载/邻居/防病毒等代码减慢了多少。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.