MVC 4 控制器中的异步和等待

Posted

技术标签:

【中文标题】MVC 4 控制器中的异步和等待【英文标题】:Async and await in MVC 4 Controller 【发布时间】:2012-12-07 05:03:08 【问题描述】:

每次我尝试使用新的 AsyncAwait 运算符并从数据库返回对象集合时,我都会收到 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 文件的 &lt;system.web&gt; 部分下注释掉以下行来使 [ChildActionOnly] 异步工作。

<system.web>
    <!--<httpRuntime targetFramework="4.5" />-->

编辑: 当您为您的情况找到真正的解决方案时,请考虑这是一种解决方法。请在下方查看 Leri 的 cmets。

【讨论】:

嗯,实际上,它有效,但它只是真的很奇怪为什么。我很想听听为什么。 刚刚检查,注释掉会使您的网络应用程序定位到根本没有异步/等待的 .net 4.0。基本上,您将失去它的所有收益。所以...这不是解决方案

以上是关于MVC 4 控制器中的异步和等待的主要内容,如果未能解决你的问题,请参考以下文章

.net core 和 Mvc api 行为之间的区别

ASP.NET MVC 4 异步加载控制器

与 MVC 3、.NET 4.5 和 EF 6 并行获取数据

ASP.NET MVC4 异步控制器 - 为啥要使用?

每当使用异步时,ASP.Net MVC 4 控制器就会挂起

什么时候应该在 ASP.NET MVC 中使用异步控制器?