C# 异步/等待的死锁

C# 异步/等待的死锁,c#,asp.net-mvc,async-await,synchronizationcontext,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 }

假设我正在编写一个自定义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);
  }
}
公共类MyActionFilter:System.Web.Mvc.ActionFilterAttribute
{
公共覆盖无效OnActionExecuted(ActionExecuteContext ctx)
{
var stuff=ConfigureAwaitHelper1().Result;
//做事
}
公共覆盖无效OnActionExecuting(ActionExecutingContext ctx)
{
var stuff=ConfigureAwaitHelper2().Result;
//做事
}
专用异步任务配置AwaitHelper1()
{
var result=await client.GetAsStringAsync(“blah.com”).ConfigureAwait(false);
返回结果;
}
专用异步任务配置AwaitHelper2()
{
返回await client.GetAsStringAsync(“blah.com”).ConfigureAwait(false);
}
}
为什么
OnActionExecuting
会死锁,而
OnActionExecuted
不会死锁?我看不出两者之间的根本区别。返回操作只在异步任务完成后发生,这相当于在返回结果之前将结果放入“匿名返回”局部变量,因此我不明白为什么前者会死锁

为什么OnActionExecuting会死锁,而OnActionExecuted不会


我很惊讶它居然能起作用。出现死锁的原因是,您正在调用
任务上的
.Result
。这是邪恶的,你应该只在控制台应用程序中调用
.Result
.Wait

你在问“当我以一种方式违反规则时,它不起作用,但当我以另一种方式违反规则时,它起作用,为什么允许我以第二种方式违反规则”,答案是不允许你以第二种方式违反规则,你很幸运没有被发现违反规则。我不知道为什么第二个可以工作,但对我来说这并不重要,因为你无论如何都不应该阻止它。另外,对于
.ConfigureAwait(false)
来说,要让你真正做到
。结果
没有死锁,调用链中的每个等待都必须设置
。ConfigureAwait(false)
。如果有一个没有,而等待是导致第二次评估发生的原因,那么你将陷入僵局。您需要显示
client.GetAsStringAsync
的代码以及它下面的每个异步/等待调用,直到找到仍然包含上下文数据的调用为止。我还有什么选择
ActionFilterAttribute
是同步的,我无法控制
客户端
。我知道您一直在担心这个问题,但我们假设这个示例已经完成,并且在
客户机.GetAsStringAsync()
中没有进一步的配置。您能否再次检查它是否是
OnActionExecuting
死锁的一个,而不是
OnActionExecuted
?可能的重复