J'ai une interface avec des fonctions asynchrones. Certaines des classes qui implémentent l'interface n'ont rien à attendre, et certaines pourraient simplement lancer. C'est un peu ennuyeux avec tous les avertissements.
Lorsque vous n'utilisez pas await dans une fonction asynchrone.
Est-il possible de supprimer le message?
public async Task<object> test()
{
throw new NotImplementedException();
}
avertissement CS1998: Cette méthode asynchrone ne dispose pas d'opérateurs «d'attente» et s'exécutera de manière synchrone. Pensez à utiliser l'opérateur 'await' pour attendre les appels d'API non bloquants, ou 'await Task.Run (...)' pour effectuer un travail lié au processeur sur un thread d'arrière-plan.
c#
asynchronous
Simon
la source
la source
Réponses:
Les méthodes reviennent
Task
, je crois.async
est un détail d'implémentation, il ne peut donc pas être appliqué aux méthodes d'interface.Dans ces cas, vous pouvez profiter du fait qu'il
async
s'agit d'un détail d'implémentation.Si vous avez rien à
await
, vous pouvez simplement revenirTask.FromResult
:Dans le cas du lancer
NotImplementedException
, la procédure est un peu plus verbeuse:Si vous avez beaucoup de méthodes à lancer
NotImplementedException
(ce qui en soi peut indiquer qu'une refactorisation au niveau de la conception serait bonne), alors vous pouvez résumer la verbosité dans une classe d'assistance:La classe d'assistance réduit également les déchets que le GC devrait autrement collecter, car chaque méthode avec le même type de retour peut partager ses objets
Task
etNotImplementedException
.J'ai plusieurs autres exemples de type "constante de tâche" dans ma bibliothèque AsyncEx .
la source
Task
. Au lieu de cela, votre méthode lancera avant même d'avoir une chance de créer un fichierTask
. Je pense vraiment que le meilleur modèle est de définir uneasync
méthode sansawait
opérateur. Cela garantit que le code de la méthode est entièrement traité dans le cadre duTask
.await Task.FromResult(0);
à votre méthode. Cela ne devrait pas avoir d'impact significatif sur les performances (contrairement à Task.Yield ()).return Task.CompletedTask;
- le plus simple de tous.Une autre option, si vous voulez garder le corps de la fonction simple et ne pas écrire de code pour le supporter, est simplement de supprimer l'avertissement avec #pragma:
Si cela est assez courant, vous pouvez placer l'instruction disable en haut du fichier et omettre la restauration.
http://msdn.microsoft.com/en-us/library/441722ys(v=vs.110).aspx
la source
Une autre façon de conserver le mot-clé async (au cas où vous voudriez le conserver) est d'utiliser:
Une fois que vous remplissez la méthode, vous pouvez simplement supprimer l'instruction. J'utilise beaucoup cela, surtout lorsqu'une méthode peut attendre quelque chose, mais pas toutes les implémentations.
la source
Task.Run
appel.Task.CompletedTask
ne semble plus exister.Task.FromResult
c'est la meilleure réponse. Pour cette question, si vous êtes allez jeter une exception, il semble une autre réponse est entré en jeu en ce qui concerneTask.FromException
ce qui en fait jamais la solution idéale. Accepteriez-vous?Il y a une différence entre les solutions et à proprement parler, vous devez savoir comment l'appelant va appeler la méthode async, mais avec le modèle d'utilisation par défaut qui suppose ".Wait ()" sur le résultat de la méthode - " return Task.CompletedTask " est la meilleure solution.
Remarque:
FromResult
ne peut pas être comparé directement.Code de test:
}
la source
#pragma
ci semble entraîner des frais généraux. Probablement autant de frais généraux que si, au lieu de renvoyer,CompletedTask
vous avez créé et complété un fichierAsyncOperation
. Ce serait bien de pouvoir dire au compilateur qu'il est correct de l'ignorer lorsque la méthode s'exécute de toute façon de manière synchrone.Task.CompletedTask
est-il similaireTask.FromResult
? Il serait intéressant de savoir - je m'attends à ce que FromResult soit le plus analogue et toujours le plus performant si vous devez renvoyer une valeur.Je sais que c'est un ancien fil, et peut-être que cela n'aura pas le bon effet pour toutes les utilisations, mais ce qui suit est aussi proche que possible de pouvoir simplement lancer une NotImplementedException lorsque je n'ai pas encore implémenté de méthode, sans modifier la signature de la méthode. Si c'est problématique, je serais heureux de le savoir, mais cela m'importe peu: je ne l'utilise que pendant le développement de toute façon, donc sa performance n'est pas si importante. Pourtant, je serais heureux d'apprendre pourquoi c'est une mauvaise idée, si c'est le cas.
Voici le type que j'ai ajouté pour rendre cela possible.
la source
Tout comme une mise à jour de la réponse de Stephen, vous n'avez plus besoin d'écrire la
TaskConstants
classe car il existe une nouvelle méthode d'assistance:la source
Si vous êtes déjà lié à Reactive Extension, vous pouvez également faire:
Reactive et async / await sont tous deux incroyables en eux-mêmes, mais ils jouent également bien ensemble.
Les éléments nécessaires sont:
la source
Cela pourrait se produire cs1998 ci-dessous.
Ensuite, vous pouvez réformer ci-dessous.
la source
Vous pouvez essayer ceci:
la source
Essaye ça:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Await.Warning", "CS1998:Await.Warning")]
Voir: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.suppressmessageattribute?view=netframework-4.7.2
la source
Si vous n'avez rien à attendre, renvoyez Task.FromResult
la source
Voici quelques alternatives en fonction de la signature de votre méthode.
la source
la source
Vous pouvez supprimer le mot-clé async de la méthode et lui demander simplement de renvoyer Task;
la source