Deadlock with async/await

本文关键字:await async with Deadlock | 更新日期: 2023-09-27 17:57:28

假设我正在编写一个自定义MVC过滤器,它在方法重写中执行一些异步调用,如下所示:

public class MyActionFilter : System.Web.Mvc.ActionFilterAttribute
{
  public override void OnActionExecuted(ActionExecutedContext ctx)
  {
    var stuff = ConfigureAwaitHelper1().Result;
    // do stuff
  }
  public override void OnActionExecuting(ActionExecutingContext ctx)
  {
    var stuff = ConfigureAwaitHelper2().Result;
    // do stuff
  }
  private async Task<string> ConfigureAwaitHelper1()
  {
    var result = await client.GetAsStringAsync("blah.com").ConfigureAwait(false);
    return result;
  }
  private async Task<string> ConfigureAwaitHelper2()
  {
    return await client.GetAsStringAsync("blah.com").ConfigureAwait(false);
  }
}

为什么OnActionExecuting死锁,而OnActionExecuted不死锁?我看不出两者之间有什么根本的区别。返回的行为只有在异步任务完成后才会发生,这相当于在返回结果之前将结果放入"匿名返回"本地var中,所以我不明白为什么前者会死锁。

Deadlock with async/await

为什么OnActionExecuting死锁,而OnActionExecuted没有?

我很惊讶它能起作用。您遇到死锁的原因是您正在Task上调用.Result。这是邪恶的,您应该只在控制台应用程序中调用.Result.Wait