Est-Tâche.Résultat le même que .GetAwaiter.GetResult()?
J'ai récemment été la lecture d'un code qui utilise beaucoup de méthodes asynchrones, mais alors parfois besoin de les exécuter de manière synchrone. Le code n':
Foo foo = GetFooAsync(...).GetAwaiter().GetResult();
Est-ce le même que
Foo foo = GetFooAsync(...).Result;
- À partir de la documentation de
GetResult
: "Ce type et ses membres sont destinés à une utilisation par le compilateur." Autre personne ne devrait pas l'utiliser. - Ceci est appelé "la synchronisation via async", et, sauf si vous savez comment la tâche est mise en œuvre peut être un vraiment mauvaise idée. Il peut instantanément blocage dans de nombreux cas (un
async
/await
méthode MVC, par exemple) - Ne pas Bloquer sur Async Code
- Dans le monde réel, nous avons les constructeurs, nous avons "sans attendre" interfaces nous avons besoin pour mettre en œuvre, et il nous est donné de méthodes asynchrones partout. Je serais heureux d'utiliser quelque chose qui fonctionne sans que je me demande pourquoi il est "dangereux", "ne pas utiliser" ou "éviter à tout prix". À chaque fois je dois me débattre avec async à son tour d'un mal de tête.
Vous devez vous connecter pour publier un commentaire.
Assez bien. Une petite différence: si le
Task
échoue,GetResult()
va juste jeter l'exception causé directement, tandis queTask.Result
va jeter unAggregateException
. Cependant, ce qui est le point de l'utilisation de l'une de celles où il estasync
? L'100x meilleure option est d'utiliserawait
.Aussi, vous n'êtes pas censé utiliser
GetResult()
. Il est destiné à être pour le compilateur d'utiliser uniquement, pas pour vous. Mais si vous ne voulez pas l'ennuyeuxAggregateException
, l'utiliser.async Task
les tests unitaires, et depuis un certain temps maintenant.Result
.The 100x better option is to use await.
Je déteste ce type de déclarations, si je pouvais claqueawait
en face d'elle, je le ferais. Mais, quand j'essaie de faire async code du travail à l'égard des non-async code comme ce qui arrive souvent à moi beaucoup dans Xamarin, je finis par avoir à utiliser des choses commeContinueWith
un lot afin de faire il pas de blocage de l'INTERFACE utilisateur. Edit: je sais que c'est vieux, mais ce n'est pas de soulager ma frustration de trouver les réponses que l'état de sans solutions de rechange pour les situations où vous ne pouvez pas utiliserawait
..GetAwaiter.Result
est recommandé d'utiliser à la place de.Result
. Votre réponse est trompeur... consultez les Microsoft Blog.GetAwaiter().GetResult()
Task
, mais l'appel n'est pas encore prêt ou l'utilise par exemple dans son constructeur.Task.GetAwaiter().GetResult()
est préféré auTask.Wait
etTask.Result
parce qu'elle se propage exceptions plutôt que de les envelopper dans unAggregateException
. Cependant, les trois méthodes de provoquer des risques de blocage et le pool de thread la famine questions. Ils devraient tous être évités en faveur deasync/await
.La citation ci-dessous explique pourquoi
Task.Wait
etTask.Result
ne pas se contenter de contenir la propagation d'exception comportement deTask.GetAwaiter().GetResult()
(en raison d'un "très haut niveau de compatibilité de la barre").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
Task.GetAwaiter().GetResult()
est équivalent àawait task
. Je suppose que la première option est utilisée lorsque la méthode ne peut pas être marqué avecasync
(constructeur par exemple). Est-ce exact? Si oui, alors il entre en collision avec la top réponse @Il'sNotALieTask.Wait
etTask.Result
(dans tous les trois vont bloquer de façon synchrone et ont le potentiel des blocages), maisTask.GetAwaiter().GetResult()
a l'exception de propagation de comportement de l'attendent tâche.https://github.com/aspnet/Security/issues/59
Task.WhenAll(task1, task2).GetAwaiter().GetResult();
.Une autre différence, c'est quand
async
fonction renvoie justeTask
au lieu deTask<T>
alors vous ne pouvez pas utiliserAlors que
fonctionne toujours.
Je sais que l'exemple de code dans la question, pour le cas
Task<T>
, cependant, la question est posée d'une manière générale.Result
avecGetIntAsync()
qui renvoieTask<int>
pas seulementTask
. Je vous suggère de lire ma réponse encore une fois.GetFooAsync(...).Result
à l'intérieur une fonction qui renvoieTask
. Cela fait maintenant de sens, car il n'y a aucun vide Propriétés en C# (Task.Result
est une propriété), mais vous pouvez bien appeler une méthode void.Comme déjà mentionné, si vous pouvez utiliser
await
. Si vous avez besoin pour exécuter le code synchrone comme vous le mentionnez.GetAwaiter().GetResult()
,.Result
ou.Wait()
est un risque pour les blocages comme beaucoup l'ont dit dans les commentaires/réponses. Puisque la plupart d'entre nous aiment les oneliners vous pouvez les utiliser pour.Net 4.5<
L'acquisition d'une valeur par l'intermédiaire d'une méthode asynchrone:
Syncronously de l'appel d'une méthode async
Pas de l'impasse problèmes ne se produisent en raison de l'utilisation de
Task.Run
.Source:
https://stackoverflow.com/a/32429753/3850405
source : c# 7.0 en un Mot