En attente d’async / wait à l’intérieur d’une tâche

J’ai cette construction dans ma main() , qui crée

 var tasks = new List(); var t = Task.Factory.StartNew( async () => { Foo.Fim(); await Foo.DoBar(); }); //DoBar not completed t.Wait(); //Foo.Fim() done, Foo.DoBar should be but isn't 

Cependant, lorsque .Wait , il n’attendra pas l’appel de DoBar() . Comment puis-je le faire attendre?

Il est déconseillé d’utiliser Task.Factory.StartNew avec async-await Task.Factory.StartNew , vous devriez plutôt utiliser Task.Run :

 var t = Task.Run( async () => { Foo.Fim(); await Foo.DoBar(); }); 

L’ Task.Factory.StartNew été créée avant le modèle asynchrone basé sur les tâches (TAP) et async-await . Il renverra Task car vous démarrez une tâche avec une expression lambda asynchrone et renvoie donc une tâche. Unwrap va extraire la tâche interne, mais Task.Run fera implicitement pour vous.


Pour une comparaison plus approfondie, il existe toujours un article pertinent de Stephen Toub: Task.Run vs Task.Factory.StartNew

Il semble que je reçois la fonctionnalité désirée en Unwrap() la tâche. Je ne suis pas sûr de comprendre le raisonnement derrière cela, mais je suppose que cela fonctionne.

 var t = Task.Factory.StartNew( async () => { Foo.Fim(); await Foo.DoBar(); }).Unwrap(); 

edit: J’ai cherché la description de Unwrap() : Creates a proxy Task that represents the asynchronous operation of a Task> Je pensais que c’était traditionnellement ce que la tâche faisait, mais si je dois appeler un déroulement, je suppose C’est très bien.

Récemment, j’ai rencontré un problème similaire et j’ai compris que tout ce que vous deviez faire était que DoBar() renvoie une valeur et utilisait .Result au lieu d’attendre.

 var g = Task.Run(() => func(arg)); var val = g.Result; 

Cela attend que func renvoie sa sortie et l’assigne à val.