Crear una tarea completa

Quiero crear una Task completa (no Task ). ¿Hay algo incorporado en .NET para hacer esto?

Una pregunta relacionada: crea una tarea completada

La versión más reciente de .Net (v4.6) está agregando solo eso, una Task.CompletedTask incorporada :

 Task completedTask = Task.CompletedTask; 

Esa propiedad se implementa como un singleton sin locking por lo que casi siempre utilizará la misma tarea completada.

Task se puede convertir implícitamente en Task , de modo que solo obtenga una Task (con cualquier T y cualquier valor) y úselo. Puede usar algo como esto para ocultar el hecho de que hay un resultado real allí, en alguna parte.

 private static Task completedTask = Task.FromResult(false); public static Task CompletedTask() { return completedTask; } 

Tenga en cuenta que dado que no estamos exponiendo el resultado, y la tarea siempre se completa, podemos almacenar en caché una única tarea y volver a utilizarla.

Si usa .NET 4.0 y no tiene FromResult , puede crear el suyo usando TaskCompletionSource :

 public static Task FromResult(T value) { var tcs = new TaskCompletionSource(); tcs.SetResult(value); return tcs.Task; } 

Mi método preferido para hacer esto es llamar a Task.WhenAll() sin argumentos. La documentación de MSDN establece que “Si la matriz / enumerable suministrada no contiene tareas, la tarea devuelta pasará inmediatamente a un estado RanToCompletion antes de que se devuelva a la persona que llama”. Eso suena como lo que quieres.

Actualización: encontré la fuente en el origen de referencia de Microsoft ; allí puede ver esa Tarea. Cuando Todo contiene lo siguiente:

 return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait Task.CompletedTask : new WhenAllPromise(tasks); 

Entonces Task.CompletedTask es de hecho interno, pero se expone llamando a WhenAll () sin argumentos.

Yo usaría Task.Delay(0) . Internamente, devuelve una instancia en caché de una Task completada Task . Esto es exactamente lo que la respuesta actual sugiere hacer de todos modos, solo que ahora no tiene que almacenar en caché una instancia usted mismo, ni tiene valores de basura poco elegantes en su código.

Tal vez esté pensando que puede usar Task.Yield() lugar, pero resulta que el resultado de Task.Yield() no es un subtipo de Task , mientras que el resultado de Task.Delay(0) es. Esa es una de las sutiles diferencias entre los dos.

Puede usar Task.FromResult (en .NET 4.5) para devolver una Task completada Task .

Si necesita una Task no genérica, siempre puede usar Task.FromResult(0) o similar, ya que Task es una subclase de Task .

Para .Net 4.6 y uso superior

 return Task.CompletedTask; 

Para una versión más baja, puedes usar

 return new Task(() => { }); 

Puede usar Nito.AsyncEx.TaskConstants.Completed de una gran biblioteca AsyncEx de Stephen Cleary .

Qué tal si:

 #pragma warning disable 1998 public async Task emptyTask() { } #pragma warning restre 1998 

Puede omitir la supresión de advertencia si no le importa.