ASP.NET MVC 4 async child action

j'ai un ASP.NET MVC 4 application targeting. net 4.5. Une de nos actions enfant lance un appel à un service web en utilisant HttpClient.

puisque nous bloquons IO en attendant la réponse HttpClient, il est très logique de convertir le code en motif async/wait. Cependant, lorsque MVC4 tente d'exécuter l'action enfant, nous recevons le message d'erreur suivant:

HttpServerUtility.Exécuter bloquée en attendant asynchrone opération à réaliser.

à première vue, il semble que MVC4 ne supporte pas l'async/l'attente dans le cadre d'une action enfant. La seule option restante est d'exécuter en utilisant du code synchrone et de forcer une "attente" sur la tâche async.

comme nous le savons tous, touchant .Le résultat ou l' .Wait() sur une tâche asynchrone dans un ASP.NET le contexte qui va provoquer un blocage immédiat. Ma logique asynchrone est enveloppée dans une bibliothèque de classe, donc je ne peux pas utiliser le "attendre blah.ConfigureAwait (false)" trick. Rappeler, marquer "async" sur l'action de l'enfant et utiliser l'attente provoque une erreur, et cela m'empêche de configurer l'attente.

je suis peinte dans un coin à ce point. Est-il mode de consommation des méthodes async dans une action MVC 4 enfant? On dirait un insecte sans solution de rechange.

28
demandé sur ShadowChaser 2012-10-05 07:34:36

2 réponses

il y a encore des parties de MVC qui ne sont pas async-friendly; j'espère que ces questions seront traitées dans l'avenir. Veuillez créer un problème Connect ou UserVoice pour cela.

ma logique asynchrone est enveloppée dans une bibliothèque de classe, donc je ne peux pas utiliser le "attendre blah.ConfigureAwait (false)" trick.

Vous avez probablement devrait ajouter ConfigureAwait(false) pour les appels dans votre bibliothèque de classe (si vous pouvez).

Vous pouvez également pirater une solution alternative. Si votre bibliothèque de classe de la méthode n'a pas besoin de l'ASP.NET contexte, alors vous pourriez avoir un thread du pool ne le (a)en attente pour vous:

try
{
    var result = Task.Run(async () => { await MyHttpRequest(...); }).Result;
}
catch (AggregateException ex) { ... }

L'effet est similaire à ConfigureAwait(false): depuis MyHttpRequest fonctionne dans un contexte de pool de threads, il ne tentera pas d'entrer ASP.NET contexte lorsqu'il est terminé.

32
répondu Stephen Cleary 2014-09-14 20:51:04

le format de la réponse de Stephen n'a pas tout à fait fonctionné pour moi (peut-être que c'est un problème async noob, mais hé).

j'ai dû écrire l'expression async dans ce format pour obtenir une valeur de retour fortement dactylographiée.

Person myPerson = Task.Run(() => asyncMethodWhichGetsPerson(id)).Result;
5
répondu David Spence 2016-01-27 11:38:49