[英]Deadlock when calling an async method inside a non async action
We have a web application which consists of a Web API consumed by our UI.我们有一个 web 应用程序,它由我们的 UI 使用的 Web API 组成。 The web application is installed on different servers (tests before installing it by our clients).
web 应用程序安装在不同的服务器上(在我们的客户安装之前进行测试)。
On one server, we get a deadlock by the following endpoint:在一台服务器上,我们通过以下端点获得了死锁:
[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)
is an async
method: 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;
}
When I remove the async signature everything is working as expected, according to this article it is normal to have a deadlock.当我删除异步签名时,一切都按预期工作,根据这篇文章,出现死锁是正常的。
Could you please explain me why this works in the other servers?你能解释一下为什么这在其他服务器上有效吗?
Thanks in advance for your help在此先感谢您的帮助
Could you please explain me why this works in the other servers?
你能解释一下为什么这在其他服务器上有效吗?
In order for the deadlock to occur, there are three necessary parts:为了使死锁发生,有三个必要的部分:
await
(without ConfigureAwait(false)
) that acts asynchronously .await
(没有ConfigureAwait(false)
)。async
method to finish.async
方法完成。 All servers also have this. Most likely, the difference in behavior is due to the second part: an await
that acts asynchronously.最有可能的是,行为上的差异是由于第二部分:异步操作的
await
。 await
first examines its awaitable (eg, the Task
passed to it), and if that awaitable is complete, then it continues executing the async
method synchronously . await
首先检查它的 awaitable(例如,传递给它的Task
),如果该 awaitable 完成,那么它会继续同步执行async
方法。
Specifically, this would happen if the Task<NameDTO>
returned from GetAsync
completed before the calling code hit the .Result
.具体来说,如果从
GetAsync
返回的Task<NameDTO>
在调用代码命中.Result
之前完成,就会发生这种情况。 This would have to be extremely fast, but it's possible depending on caching, how fast your network hop is, how much the code is slowed down by load/neighbors/anti-virus, etc.这必须非常快,但这可能取决于缓存、网络跃点的速度、加载/邻居/防病毒等代码减慢了多少。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.