web-dev-qa-db-fra.com

Async PartialView provoque l'exception "HttpServerUtility.Execute block ..."

J'ai une vue partielle qui tente de récupérer un IEnumerable<Post> de la base de données en utilisant async ...

Méthode

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

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

Vue partielle

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

Et puis si j'essaye de l'appeler

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

Je reçois l'exception suivante

HttpServerUtility.Execute bloqué en attendant la fin d'une opération asynchrone.

Description: une exception non gérée s'est produite lors de l'exécution de la demande Web en cours. Veuillez consulter la trace de la pile pour plus d'informations sur l'erreur et son origine dans le code.

Détails des exceptions: System.InvalidOperationException: HttpServerUtility.Execute bloqué en attendant la fin d'une opération asynchrone.

Pourquoi ai-je cette erreur? Ça ne devrait pas marcher?

77
BrunoLM

Les actions enfants doivent être appelées de manière synchrone. Issue 601 Je ne suis pas non plus au courant des mises à jour récentes des bibliothèques MVC actuelles autorisant cette fonctionnalité.

Un commentaire sur le numéro 601 indique que cette fonctionnalité est ajoutée dans MVC vNext, aka. MVC6. Les actions enfants semblent être remplacées par ViewComponent, qui peut être invoqué de manière asynchrone à partir d'une vue comme ci-dessous. Exemples complets ici et ici

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

Pour plus d'informations sur MVC6, http://www.asp.net/vnext/overview/aspnet-vnext/overview

Note: Cette réponse est juste une formalité, donc la question peut être marquée comme réponse

89
Xenolightning

Une solution de contournement à ce problème consiste à rendre la méthode synchrone comme requis par MVC, à effacer le SynchronizationContext, à appeler la méthode async et à attendre le résultat, puis à restaurer le contexte.

voir ma réponse complète ici

2
Herre Kuijpers