Async PartialView вызывает исключение «HttpServerUtility.Execute blocked…»

85

У меня есть частичное представление, которое пытается получить IEnumerable<Post>из базы данных с помощью async ...

Метод

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 заблокирован в ожидании завершения асинхронной операции.

Описание: необработанное исключение произошло во время выполнения текущего веб-запроса. Просмотрите трассировку стека для получения дополнительных сведений об ошибке и ее происхождении в коде.

Сведения об исключении: System.InvalidOperationException: HttpServerUtility.Execute заблокирован во время ожидания завершения асинхронной операции.

Почему я получаю эту ошибку? Разве это не должно работать?

BrunoLM
источник

Ответы:

97

Дочерние действия должны вызываться синхронно. Проблема 601. Мне также неизвестны какие-либо недавние обновления текущих библиотек MVC, позволяющие использовать эту функцию.

Комментарий к проблеме 601 намекает на добавление этой функции в MVC vNext, также известную как. MVC6. Дочерние действия, которые должны быть заменены, ViewComponentмогут быть вызваны асинхронно из представления, как показано ниже. Полные примеры здесь и здесь

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

Чтобы узнать больше о MVC6, посетите http://www.asp.net/vnext/overview/aspnet-vnext/overview

Примечание. Этот ответ является формальным, поэтому вопрос можно пометить как ответ.

Ксенололния
источник
ссылка 601 больше не действительна
Serge
6

Обходной путь для этой проблемы - сделать метод синхронным, как того требует MVC, очистить SynchronizationContext, вызвать асинхронный метод и дождаться результата, а затем восстановить контекст.

см. мой полный ответ здесь

Herre Kuijpers
источник
3
(Этот пост не дает качественного ответа на вопрос. Измените свой ответ или просто опубликуйте его как комментарий к вопросу).
sɐunıɔ ןɐ qɐp