17

每次我尝试使用 newAsyncAwait运算符并从数据库返回对象集合时,我都会遇到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 在等待异步操作完成时被阻塞。

4

3 回答 3

29

首先,您不能对子操作使用异步处理,我想这就是您想要做的。

其次,您没有在此处通过启动另一个线程来执行任何异步处理,以使用以下代码行执行您的代码:

Task.Run(() => GetAllEnvironments());

它会在一天结束时阻塞一个线程,你将只有上下文切换开销。EF6 将支持异步处理。对于纯 ADO.NET 的异步查询,请查看:

ASP.NET MVC 4 中使用基于任务的异步编程模型 (TAP) 的异步数据库调用

于 2012-12-19T19:09:26.680 回答
0

自从回答这个问题已经有一段时间了,但另一种方法如下:

从一个动作中调用你的方法

@Html.Action("YourSyncMethod", "YourController")

将其定义为正常的同步操作

public ActionResult YourSyncMethod()

然后在里面调用你的异步方法

var taskResponse = YourAsyncMethod(); 

它将返回一个包含您需要的模型

private async Task<YourModel> YourAsyncMethod()

它似乎比篡改配置选项或创建更复杂的代码更简单

于 2019-10-04T09:11:04.560 回答
-2

这个问题已经有一段时间没有回答了。<system.web>但是我在使用 MVC 5 时遇到了类似的情况,我能够通过在web.config 文件部分下注释掉以下行来使 [ChildActionOnly] 异步工作。

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

编辑:当您找到适合您情况的真正解决方案时,请考虑这是一种解决方法。请参阅下面 Leri 的评论。

于 2016-04-20T14:22:46.157 回答