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>
La versión más reciente de .Net (v4.6) está agregando solo eso, una Task.CompletedTask :
Task completedTask = Task.CompletedTask;
Esa propiedad se implementa como un singleton sin bloqueo por lo que casi siempre utilizará la misma tarea completada.
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
.
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 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;
}