与异步/等待的死锁

时间:2016-07-18 21:31:05

标签: c# asp.net-mvc async-await synchronizationcontext

假设我正在编写一个自定义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中一样,所以我不明白为什么前者应该死锁。

1 个答案:

答案 0 :(得分:1)

  

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

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