簡體   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