MVC 4 控制器中的异步和等待
Posted
技术标签:
【中文标题】MVC 4 控制器中的异步和等待【英文标题】:Async and await in MVC 4 Controller 【发布时间】:2012-12-07 05:03:08 【问题描述】:每次我尝试使用新的 Async
和 Await
运算符并从数据库返回对象集合时,我都会收到 Invalid Operation
异常。当我使用它只返回一个项目时,它工作正常。
控制器代码:
public async Task<ActionResult> EnvironmentList()
EfEnvironmentDataAccess dataAccess = new EfEnvironmentDataAccess();
ICollection<Environment> environments = await dataAccess.GetAllEnvironmentsAsync();
return PartialView(environments);
查看代码:
<div class="ECURightCol">
<h3>Table Dumps</h3>
@html.Action("EnvironmentList", "Environment")
@Html.Action("ComputerList", "Computer")
@Html.Action("ProductList", "Product")
@Html.Action("InstanceList", "Instance")
@Html.Action("ProfileList", "Profile")
数据访问代码:
public ICollection<Environment> GetAllEnvironments()
using (EcuWebDataContext db = new EcuWebDataContext())
return db.Environments.OrderBy(e => e.Name).ToList();
public async Task<ICollection<Environment>> GetAllEnvironmentsAsync()
return await Task.Run(() => GetAllEnvironments());
我得到的错误是:
说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。
异常详细信息:System.InvalidOperationException:HttpServerUtility.Execute 在等待异步操作完成时被阻塞。
【问题讨论】:
【参考方案1】:首先,you cannot use asynchronous processing with child actions,我想这就是你想要做的。
其次,您不会在这里通过启动另一个线程来执行任何异步处理,以使用以下代码行执行您的代码:
Task.Run(() => GetAllEnvironments());
它会在一天结束时阻塞一个线程,你只会有上下文切换开销。 EF6 将支持异步处理。对于纯 ADO.NET 的异步查询,看看:
Asynchronous Database Calls With Task-based Asynchronous Programming Model (TAP) in ASP.NET MVC 4
【讨论】:
我在 mvc5 中遇到了这个错误。我不知道我们不能对子操作使用异步处理。只需删除 Async 即可。太好了!!!【参考方案2】:已经有一段时间没有回答这个问题了,但另一种方法如下:
从动作中调用你的方法
@Html.Action("YourSyncMethod", "YourController")
将其定义为正常的同步操作
public ActionResult YourSyncMethod()
然后在里面调用你的异步方法
var taskResponse = YourAsyncMethod();
这将返回一个包含你需要的模型
private async Task<YourModel> YourAsyncMethod()
这似乎比篡改配置选项或创建更复杂的代码更简单
【讨论】:
【参考方案3】:这个问题已经有一段时间没有回答了。但是我在使用 MVC 5 时遇到了类似的情况,我能够通过在 web.config 文件的 <system.web>
部分下注释掉以下行来使 [ChildActionOnly] 异步工作。
<system.web>
<!--<httpRuntime targetFramework="4.5" />-->
编辑: 当您为您的情况找到真正的解决方案时,请考虑这是一种解决方法。请在下方查看 Leri 的 cmets。
【讨论】:
嗯,实际上,它有效,但它只是真的很奇怪为什么。我很想听听为什么。 刚刚检查,注释掉会使您的网络应用程序定位到根本没有异步/等待的 .net 4.0。基本上,您将失去它的所有收益。所以...这不是解决方案以上是关于MVC 4 控制器中的异步和等待的主要内容,如果未能解决你的问题,请参考以下文章