ASP.NET MVC 4异步子操作

时间:2012-10-05 03:34:36

标签: asp.net-mvc asp.net-mvc-4 async-await

我有一个针对.NET 4.5的ASP.NET MVC 4应用程序。我们的一个子操作使用HttpClient调用Web服务。

由于我们阻止IO等待HttpClient响应,因此将代码转换为async / await模式非常有意义。但是,当MVC 4尝试执行子操作时,我们收到以下错误消息:

  

HttpServerUtility.Execute在等待异步操作完成时被阻止。

乍一看,似乎MVC 4不支持子动作中的异步/等待。唯一剩下的选择是使用同步代码运行并在异步任务上强制“等待”。

众所周知,在ASP.NET上下文中的异步任务上触摸.Result或.Wait()会导致立即死锁。我的异步逻辑包含在类库中,所以我不能使用“await blah.ConfigureAwait(false)”技巧。请记住,在子操作上标记“async”并使用await会导致错误,这会阻止我配置await。

此时我被画成了一个角落。是否任何方式在MVC 4子操作中使用异步方法?看起来像一个没有解决方法的平坦的bug。

2 个答案:

答案 0 :(得分:32)

仍然有一部分MVC不是async - 友好的;我希望将来能够解决这些问题。请为此创建Connect或UserVoice问题。

  

我的异步逻辑包含在类库中,所以我不能使用“await blah.ConfigureAwait(false)”技巧。

您可能ConfigureAwait(false)添加到您的类库中的调用中(如果可以的话)。

你也可以破解另一种解决方案。 如果你的类库方法不需要ASP.NET上下文,那么你可以有一个线程池线程做(a)等你:

try
{
    var result = Task.Run(async () => { await MyHttpRequest(...); }).Result;
}
catch (AggregateException ex) { ... }

效果类似于ConfigureAwait(false):由于MyHttpRequest在线程池上下文中运行,因此在完成时不会尝试进入ASP.NET上下文。

答案 1 :(得分:5)

斯蒂芬的回答格式对我来说并不合适(也许这是一个异步的noob问题,但是嘿)。

我必须以这种格式编写异步表达式以获得强类型返回值。

Person myPerson = Task.Run(() => asyncMethodWhichGetsPerson(id)).Result;