假设我正在编写一个自定义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中一样,所以我不明白为什么前者应该死锁。
答案 0 :(得分:1)
为什么OnActionExecuting死锁,而OnActionExecuted却没有?
我很惊讶它的功能完全正常。您遇到死锁的原因是您在.Result
上调用了Task
。这是邪恶的,你应该只在控制台应用程序中调用.Result
和.Wait
。