ne peut pas attendre lambda asynchrone
De considérer cela,
Task task = new Task (async () =>{
await TaskEx.Delay(1000);
});
task.Start();
task.Wait();
L'appel de la tâche.Wait() ne fait pas attendre l'achèvement de la tâche et la ligne suivante est exécutée immédiatement, mais si j'enveloppe la async expression lambda dans un appel de méthode, le code fonctionne comme prévu.
private static async Task AwaitableMethod()
{
await TaskEx.Delay(1000);
}
ensuite (mis à jour en fonction des commentaires de svick)
await AwaitableMethod();
- Dans le
AwaitableMethod
vous sont effectivement de retour et en appelant à Attendre sur la tâche retourné à partir de la .Delay (), méthode (je suis en supposant qu'elle renvoie uneTask
). Dans le lambda asynchrone vous appelez à Attendre sur laTask task
. Mais encore, je n'ai pas d'explication. - Vous devriez être très prudent sur le mélange
await
avecWait()
. Dans de nombreux cas, cela peut conduire à des blocages. - trouvé un grand exemple sur le mélange
await
avecWait()
Vous devez vous connecter pour publier un commentaire.
Dans votre lambda exemple, lorsque vous appelez
task.Wait()
, vous êtes en attente sur la nouvelle Tâche que vous avez construit, pas le délai de la Tâche dont il retourne. Pour obtenir votre choix de retard, vous devez également attendre sur la Tâche:Vous pouviez éviter de construire une nouvelle Tâche, et juste avoir une Tâche à traiter au lieu de deux:
task.Result.Wait()
vous pouvez également fairetask.Unwrap().Wait()
(ouUnwrap<T>()
pour les non-méthodes void). La nouvelleTask.Run
méthodes automatiquement déballer de sorte que vous n'attendez que sur la tâche.async
de mots-clés; il est très déroutant.Vous devez utiliser
TaskEx.RunEx
.Il prend nativement en charge l'exécution de
async
méthodes sur laTaskPool
par l'attente de l'intérieur de la tâche en interne. Sinon, vous rencontrerez le problème auquel vous êtes confronté, où seul l'extérieur de la tâche est attendu, qui, évidemment, se termine immédiatement, laissant une tâche qui doit encore en attente, ou dans votre cas (et même pire) un vide lambda qui ne peut pas être attendu.Sinon, vous pouvez attendre la tâche deux fois, vous permettant de construire votre extérieur tâche correctement (ce qui actuellement vous n'êtes pas).
Code actuel (fixe):
À L'Aide De TaskEx.RunEx: