【问题标题】:Async and await in MVC 4 ControllerMVC 4 控制器中的异步和等待
【发布时间】: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 在等待异步操作完成时被阻塞。

【问题讨论】:

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


    【解决方案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。基本上,您将失去它的所有收益。所以...这不是解决方案
      猜你喜欢
      • 1970-01-01
      • 2012-10-14
      • 2023-03-08
      • 1970-01-01
      • 2018-03-12
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多