Async PartialView вызывает " HttpServerUtility.Выполнить заблокировали..." исключение


у меня есть частичный вид, что пытается получить 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.Выполнение заблокировано в ожидании завершения асинхронной операции.

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

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

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

2 63

2 ответа:

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

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

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

для получения дополнительной информации о MVC6 проверьте, http://www.asp.net/vnext/overview/aspnet-vnext/overview

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

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

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