Tengo una interfaz con algunas funciones asincrónicas.
Los métodos regresan Task, creo. asynces un detalle de implementación, por lo que no se puede aplicar a métodos de interfaz.
Algunas de las clases que implementan la interfaz no tienen nada que esperar, y algunas pueden simplemente lanzar.
En estos casos, puede aprovechar el hecho de que asynces un detalle de implementación.
Si no tiene nada que hacer await, puede simplemente regresar Task.FromResult:
public Task<int> Success() // note: no "async"
{
... // non-awaiting code
int result = ...;
return Task.FromResult(result);
}
En el caso de lanzar NotImplementedException, el procedimiento es un poco más prolijo:
public Task<int> Fail() // note: no "async"
{
var tcs = new TaskCompletionSource<int>();
tcs.SetException(new NotImplementedException());
return tcs.Task;
}
Si tiene muchos métodos lanzando NotImplementedException(lo que en sí mismo puede indicar que una refactorización a nivel de diseño sería buena), entonces podría resumir la palabra en una clase auxiliar:
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 clase auxiliar también reduce la basura que el GC tendría que recolectar, ya que cada método con el mismo tipo de retorno puede compartir sus objetos Tasky NotImplementedException.
Tengo varios otros ejemplos de tipo "constante de tarea" en mi biblioteca AsyncEx .