2012-08-09 149 views
11

我需要内防止死锁不使用的await调用异步方法时

public override void OnActionExecuting(ActionExecutingContext filterContext) 

从调用返回一个Task的方法它不会让我做这个方法异步它抛出以下

异步模块或处理程序在异步操作仍未完成时完成。

,并呼吁

entityStorage.GetCurrentUser().Result 

当我得到一个僵局。我怎样才能避免这种情况?

我一直在玩弄它的到来了东西一样

entityStorage.GetCurrentUser().Result.ConfigureAwait(false).GetAwaiter().GetResult(); 

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

+0

在这里找到了答案http://stackoverflow.com/a/5097066/168012如果有人有更好的解决方案,请分享 – Tom 2012-08-09 16:56:50

+2

您是从'AsyncController'而不是'Controller'派生的吗? – 2012-08-10 00:53:27

+0

请[在此投票](https://aspnet.codeplex.com/workitem/9582)为MVC团队添加对“异步”动作过滤器的支持。 – 2013-06-11 14:21:19

回答

2

由于await只是语法糖,因此编译器会为您重写一个延续,最直接的途径就是采取任何代码来遵循您的等待并使其成为ContinueWith调用。

所以,像这样:

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

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

更新:请求vote here为MVC团队添加支持async动作过滤器。

+0

我很难找到这样说的链接/页面,但我曾经有人告诉过我,如果提供一个链接(尤其是一个外部的链接),您应该将关键位复制到SO回答。这里有点提到,FWIW:http://meta.stackexchange.com/questions/118582/what-is-an-acceptable-answer – 2012-08-09 17:55:31

+0

你是对的;您所指的元问题最近被删除,作为“让我们成为更好的地方”战略的一部分。然而,正如Jon Skeet评论的那样:如果我知道答案并且只有时间发布链接,那么总比没有好。 – 2012-08-10 00:10:28

+0

我遇到的问题是,如果我尝试使用async关键字并使方法异步,则该方法抛出“异步操作尚未完成时异步模块或处理程序已完成”。 – Tom 2012-08-16 14:00:17

1

如果MUST转换非同步进行同步。

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的回答。

相关问题