Attendre ou de la Tâche.FromResult
J'ai un service permet de dire,
public interface ISomeService
{
Task<bool> DoSomeExpensiveCheckAsync(string parameter);
}
Et j'ai cette classe pour utiliser le service. Il a juste besoin de faire quelques simples null vérifications et puis retourner le service de réponse en retour.
public class SomeServiceConsumer
{
private readonly ISomeService _serviceClient;
public SomeServiceConsumer(ISomeService serviceClient)
{
_serviceClient = serviceClient;
}
public async Task<bool> DoSomething1Async(string someParameter)
{
if (string.IsNullOrWhiteSpace(someParameter))
{
return false;
}
return await _serviceClient.DoSomeExpensiveCheckAsync(someParameter);
}
//No async or await keywords
public Task<bool> DoSomething2Async(string someParameter)
{
if (string.IsNullOrWhiteSpace(someParameter))
{
return Task.FromResult(false);
}
return _serviceClient.DoSomeExpensiveCheckAsync(someParameter);
}
}
Dois-je faire DoSomething1Async
ou DoSomething2Async
?
Selon cette réponse, je ne devrais pas envelopper avec une inutile await
mais puis-je utiliser Task.FromResult(false)
pour un court-circuit comme dans DoSomething2Async
Mais selon cette réponse il y a des cas avec try/catch
et using
états où j'ai vraiment devrait await
avant de revenir.
Ai-je raison de dire alors, que
- Si je dois utiliser
try/catch
ouusing
puis je devraisawait
- Autrement, ne pas
await
si vous allez seulement pour le retour. Et l'utilisationTask.FromResult
pour le court-circuit
J'aime DoSomething1Async
plus, et que vous voulez le faire partout si quelqu'un dit que ce n'est pas grave :).
OriginalL'auteur labroo | 2014-11-12
Vous devez vous connecter pour publier un commentaire.
Si vous êtes inquiet à ce sujet, cache la
Task
:La
async
mot-clé enveloppements exceptions dans le retour de l'Task
, avec une bonne trace de la pile. C'est un compromis, de sécurité, de comportement pour les perf.Permet de regarder la différence des scénarios où chacun serait différent:
Juste illustrant le point ici --
IsNullOrWhiteSpace
ne fait pas de jeter des exceptions pour une raison quelconque.Autant que les traces de pile allez, async traces de la pile sont déterminés par l'endroit où vous
await
. Pas deawait
signifie que la méthode va disparaître à partir de la trace de la pile.Dire
DoSomeExpensiveCheckAsync
déclenche une exception. Dans le cas deDoSomething1Async
, la trace de la pile ressemblecaller -> DoSomething1Async -> DoSomeExpensiveCheckAsync
.Dans le cas de
DoSomething2Async
, la trace de la pile ressembleraitcaller -> DoSomeExpensiveCheckAsync
. Selon la complexité de votre code, cela peut rendre les choses difficiles à déboguer.Dans la pratique, je n'retourner directement une
Task
si je n'en connaissait pas d'exceptions seraient jetés avant, et si le nom de la méthode n'était qu'une surcharge de transfert vers une autre surcharge. Il y a toujours des exceptions à cette règle, il y a certainement des endroits que vous souhaitez afin d'optimiser les performances. Il suffit de choisir et de choisir avec soin, de réaliser que vous pourriez être la vie de vous et de vos plus difficile.J'ai édité, dans une explication.
OriginalL'auteur Cory Nelson
Il n'a pas vraiment d'importance. Si vous êtes à l'aise avec toujours marquage
Task
-de retour des méthodes avec lesasync
mot-clé puis aller de l'avant et à l'utilisationDoSomething1
.Comme vous l'avez dit, c'est un compromis:
DoSomething2
ne génère pas de l'état de la machine nécessaire pour uneasync
méthode et il est donc légèrement plus vite (mais la différence est surtout négligeable).D'autre part, il peut avoir certains des effets secondaires imprévus matière de gestion des exceptions puisque de plus en
async
méthode de l'exception pourrait être stockés dans l'retournéTask
et dans l'autre, il serait jeté régulièrement.Pour comprendre la différence, vous devez penser à ce qui allait se passer sans un
await
:var task = DoSomethingAsync("Hello")
. Si il y a une exception et la méthode est asynchrone, ce ne serait pas lever une exception. L'exception serait stocké dans la tâche et relancés surawait
. Si la méthode n'est pas asynchrone à l'exception sera levée, tout comme toute autre méthode.Voici quelques infos: stackoverflow.com/a/24441859/885318
OriginalL'auteur i3arnon