Je lisais récemment du code qui utilise beaucoup de méthodes asynchrones, mais a parfois besoin de les exécuter de manière synchrone. Le code:
Foo foo = GetFooAsync(...).GetAwaiter().GetResult();
Est-ce la même chose que
Foo foo = GetFooAsync(...).Result;
c#
async-await
Jay Bazuzi
la source
la source
GetResult
: "Ce type et ses membres sont destinés à être utilisés par le compilateur." Une autre personne ne devrait pas l'utiliser.async
/await
dans MVC, par exemple)Réponses:
Plutôt. Une petite différence cependant: si l'
Task
échec,GetResult()
lance simplement l'exception provoquée directement, tandis queTask.Result
lance unAggregateException
. Cependant, quel est l'intérêt d'utiliser l'un ou l'autre de ceux-ci quand c'estasync
? L'option 100x meilleure est d'utiliserawait
.De plus, vous n'êtes pas censé l'utiliser
GetResult()
. Il est destiné à être utilisé uniquement par le compilateur, pas pour vous. Mais si vous ne voulez pas être ennuyeuxAggregateException
, utilisez-le.la source
async Task
tests unitaires et existent depuis un certain temps maintenant.The 100x better option is to use await.
Je déteste les déclarations comme celle-ci, si je pouvais giflerawait
devant, je le ferais. Mais, quand je suis en train de récupérer le code async au travail contre le code non comme async ce qui se passe souvent me beaucoup dans Xamarin, je finis par avoir à utiliser des choses commeContinueWith
beaucoup pour le rendre interblocage pas l'interface utilisateur. Edit: Je sais que c'est vieux, mais cela n'atténue pas ma frustration de trouver des réponses qui disent ceci sans aucune alternative pour les situations où vous ne pouvez pas simplement utiliserawait
.Task.GetAwaiter().GetResult()
est préféréTask.Wait
etTask.Result
parce qu'il propage des exceptions plutôt que de les encapsuler dans unAggregateException
. Cependant, les trois méthodes peuvent entraîner des problèmes de blocage et de famine du pool de threads. Ils devraient tous être évités en faveur deasync/await
.La citation ci-dessous explique pourquoi
Task.Wait
etTask.Result
ne contient pas simplement le comportement de propagation d'exception deTask.GetAwaiter().GetResult()
(en raison d'une "barre de compatibilité très élevée").https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/
http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html
la source
Task.GetAwaiter().GetResult()
c'est équivalent àawait task
. Je suppose que la première option est utilisée lorsque la méthode ne peut pas être marquée avecasync
(constructeur par exemple). Est-ce exact? Si oui, alors il entre en collision avec la meilleure réponse @ It'sNotALieTask.GetAwaiter().GetResult()
est plus équivalent àTask.Wait
etTask.Result
(en ce que les trois se bloqueront de manière synchrone et auront le potentiel de blocages), maisTask.GetAwaiter().GetResult()
a le comportement de propagation d'exception de la tâche d'attente.https://github.com/aspnet/Security/issues/59
la source
Task.WhenAll(task1, task2).GetAwaiter().GetResult();
.Une autre différence est que lorsque la
async
fonction retourne justeTask
au lieu de,Task<T>
vous ne pouvez pas utiliserTandis que
fonctionne encore.
Je sais que l'exemple de code dans la question est pour le cas
Task<T>
, mais la question est généralement posée.la source
Result
avecGetIntAsync()
qui renvoieTask<int>
non seulementTask
. Je vous suggère de relire ma réponse.GetFooAsync(...).Result
intérieur d' une fonction qui retourneTask
. Cela a maintenant un sens, car il n'y a pas de propriétés void en C # (Task.Result
est une propriété), mais vous pouvez bien sûr appeler une méthode void.Comme déjà mentionné si vous pouvez utiliser
await
. Si vous devez exécuter le code de manière synchrone comme vous le mentionnez.GetAwaiter().GetResult()
,.Result
ou si vous.Wait()
risquez de bloquer, comme beaucoup l'ont dit dans les commentaires / réponses. Comme la plupart d'entre nous aiment les oneliners, vous pouvez les utiliser pour.Net 4.5<
Acquisition d'une valeur via une méthode asynchrone:
Appel synchrone d'une méthode asynchrone
Aucun problème de blocage ne se produira en raison de l'utilisation de
Task.Run
.La source:
https://stackoverflow.com/a/32429753/3850405
la source
source: c # 7.0 en bref
la source