run parallel method library example ejemplos create await async c# .net async-await task-parallel-library

method - task parallel library c#



Crear una tarea completa (8)

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

Una pregunta relacionada: crea una tarea completada <T>



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.


Para .Net 4.6 y uso superior

return Task.CompletedTask;

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

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


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

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



Qué tal si:

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

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


Yo usaría Task.Delay(0) . Internamente, devuelve una instancia en caché de una Task<T> completada Task<T> . 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.


Task<T> se puede convertir implícitamente en Task , de modo que solo obtenga una Task<T> (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<T> FromResult<T>(T value) { var tcs = new TaskCompletionSource<T>(); tcs.SetResult(value); return tcs.Task; }