在不使用await的情况下调用异步方法时防止死锁

时间:2012-08-09 16:32:01

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-4.0 async-await

我需要调用一个从

中返回Task的方法
public override void OnActionExecuting(ActionExecutingContext filterContext)

它不会让我使这个方法异步它抛出以下

  

异步模块或处理程序在异步时完成   手术还在等待。

并且在致电时

 entityStorage.GetCurrentUser().Result

我陷入僵局。我怎么能避免这个?

我一直在玩它,想出像

这样的东西
entityStorage.GetCurrentUser().Result.ConfigureAwait(false).GetAwaiter().GetResult();

但这不起作用。我该怎么做?我的解决方案需要使用ASP.NET 4和Async Targetting Pack,我不能使用ASP.NET 4.5作为部署到Azure。

3 个答案:

答案 0 :(得分:13)

死锁的原因是explained here。简而言之,不要阻止async代码。您应该在库ConfigureAwait(false)代码中使用async,并使用await结果(不使用ResultWait)。

更新:请vote here让MVC小组添加对async操作过滤器的支持。

答案 1 :(得分:2)

由于await只是编译器重写续集的语法糖,因此最“直接”的路径是采用任何跟随等待的代码并使其成为ContinueWith调用。

所以,比如:

entityStorage.GetCurrentUser().ContinueWith(t =>
{
    // do your other stuff here
});

答案 2 :(得分:2)

如果必须将异步转换为同步。

public User GetCurrentUserSynch()
    {
        return Task.Run(() =>
        {
            var asyncResult = entityStorage.GetCurrentUser();
            while (!asyncResult.IsCompleted)
            {
                Application.Current.TryFindResource(new object()); // This is for WPF but you can do some other nonsense action of your choosing
            }

            return asyncResult.Result;
        }).Result;
    }

否则请使用@ Stephen的答案。

相关问题