Async PartialView导致" HttpServerUtility.Execute被阻止..."例外

时间:2014-06-06 01:18:10

标签: c# asp.net-mvc entity-framework asp.net-mvc-5 entity-framework-6

我有一个部分视图,试图使用async ...

从数据库中检索IEnumerable<Post>

方法

public static class PostService
{
    public static int PostsPerPage = 50;

    public static async Task<IEnumerable<Post>> GetRecentAsync(int page = 0)
    {
        return await entityFrameworkDbContext.Posts
            .ToListAsync();
    }
}

PartialView

public async Task<ActionResult> Recent(int page = 0)
{
    return PartialView(await PostService.GetRecentAsync(page));
}

然后如果我试着打电话

@Html.Action("Recent", "Post")

我收到以下异常

  

HttpServerUtility.Execute在等待异步操作完成时被阻止。

     

描述:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

     

异常详细信息:System.InvalidOperationException:HttpServerUtility.Execute在等待异步操作完成时被阻止。

为什么会出现此错误?不应该有用吗?

3 个答案:

答案 0 :(得分:87)

必须同步调用子操作。 Issue 601我也不知道当前MVC库的最新更新是否允许此功能。

对问题601的评论,提示在MVC vNext中添加此功能,又名。 MVC6。子操作看起来被替换为ViewComponent,可以从视图中异步调用,如下所示。完整示例herehere

<div>
@await Component.InvokeAsync("YourComponent")
</div>

有关MVC6的更多信息,请查看http://www.asp.net/vnext/overview/aspnet-vnext/overview

注意:这个答案只是一种形式,所以问题可以标记为已回答

答案 1 :(得分:2)

此问题的解决方法是按照MVC的要求使方法同步,清除SynchronizationContext,调用async方法并等待结果,然后还原上下文。

查看我的全问here

答案 2 :(得分:0)

我在调用某些社交媒体网站的 API 并获取我们最近的几篇帖子并将它们显示在我们网站之一的主页上时遇到了类似的问题。

解决这个问题的方法是使用 JavaScript 从视图(或您希望显示的部分视图)获取我想在主页上显示的数据,然后使用 ID.innerHTML + = 将获取的数据挂钩到主页如以下代码所示

 <div id="ID"></div>

<script>
    var ID = document.getElementById('twitter');

    var sendHttpRequest = (method, url) => {
        var promise = new Promise((resolve, reject) => {
            var xhr = new XMLHttpRequest();

            xhr.open(method, url);

            xhr.onload = () => {
                resolve(xhr.response);
            };

            xhr.send();
        });

        return promise;
    };

    window.addEventListener('load', function () {
        sendHttpRequest('GET', '////////////// the URL for the View (Or Partial View) /////////').then((responseData) => {ID.innerHTML += responseData})

    })
</script>

希望这能帮助那些正在为这个问题寻找更快解决方案的人。

谢谢