繁体   English   中英

在非异步操作中调用异步方法时出现死锁

[英]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;
}

当我删除异步签名时,一切都按预期工作,根据这篇文章,出现死锁是正常的。

你能解释一下为什么这在其他服务器上有效吗?

在此先感谢您的帮助

你能解释一下为什么这在其他服务器上有效吗?

为了使死锁发生,有三个必要的部分:

  1. 所有服务器都将具有的一次一个线程的上下文(Core ASP.NET 之前的上下文)。
  2. 异步操作的await (没有ConfigureAwait(false) )。
  3. 其他地方的代码会阻塞该上下文中的线程,等待async方法完成。 所有服务器也有这个。

最有可能的是,行为上的差异是由于第二部分:异步操作的await await首先检查它的 awaitable(例如,传递给它的Task ),如果该 awaitable 完成,那么它会继续同步执行async方法

具体来说,如果从GetAsync返回的Task<NameDTO>在调用代码命中.Result之前完成,就会发生这种情况。 这必须非常快,但这可能取决于缓存、网络跃点的速度、加载/邻居/防病毒等代码减慢了多少。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM