J'ai une interface avec des fonctions asynchrones.
Les méthodes reviennent Task, je crois. asyncest un détail d'implémentation, il ne peut donc pas être appliqué aux méthodes d'interface.
Certaines des classes qui implémentent l'interface n'ont rien à attendre, et certaines pourraient simplement lancer.
Dans ces cas, vous pouvez profiter du fait qu'il asyncs'agit d'un détail d'implémentation.
Si vous avez rien à await, vous pouvez simplement revenir Task.FromResult:
public Task<int> Success() // note: no "async"
{
... // non-awaiting code
int result = ...;
return Task.FromResult(result);
}
Dans le cas du lancer NotImplementedException, la procédure est un peu plus verbeuse:
public Task<int> Fail() // note: no "async"
{
var tcs = new TaskCompletionSource<int>();
tcs.SetException(new NotImplementedException());
return tcs.Task;
}
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:
public static class TaskConstants<TResult>
{
static TaskConstants()
{
var tcs = new TaskCompletionSource<TResult>();
tcs.SetException(new NotImplementedException());
NotImplemented = tcs.Task;
}
public static Task<TResult> NotImplemented { get; private set; }
}
public Task<int> Fail() // note: no "async"
{
return TaskConstants<int>.NotImplemented;
}
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 Tasket NotImplementedException.
J'ai plusieurs autres exemples de type "constante de tâche" dans ma bibliothèque AsyncEx .