我有一个ASP.NET MVC 4应用程序针对.NET 4.5。我们的一个子操作使用HttpClient调用Web服务。
因为我们阻塞IO等待HttpClient响应,所以将代码转换为async / await模式是非常有意义的。然而,当MVC 4尝试执行子操作时,我们得到以下错误消息:
HttpServerUtility.Execute blocked while waiting for an asynchronous operation to complete.
乍看起来,似乎MVC 4不支持在子操作中异步/等待。唯一剩下的选项是使用同步代码运行,并对异步任务强制执行“等待”。
众所周知,在ASP.NET上下文中,触摸.Result或.Wait()会导致一个立即死锁。我的异步逻辑被包装在一个类库中,所以我不能使用“await blah.ConfigureAwait(false)”技巧。记住,对子操作标记“异步”并使用await会导致错误,并且阻止我配置等待。
解决方法
还有一些MVC的部分不是异步友好的;我希望这些将在未来得到解决。请为此创建一个Connect或UserVoice问题。
My async logic is wrapped in a class library,so I can’t use the “await blah.ConfigureAwait(false)” trick.
您可能应该添加ConfigureAwait(false)到类库中的调用(如果可以)。
你也可以黑客一个替代解决方案。如果你的类库方法不需要ASP.NET上下文,那么你可以有一个线程池线程做(a)等待你:
try { var result = Task.Run(async () => { await MyHttpRequest(...); }).Result; } catch (AggregateException ex) { ... }
效果类似于ConfigureAwait(false):因为MyHttpRequest在线程池上下文中运行,所以它不会尝试在完成时进入ASP.NET上下文。