Quiero crear un completado Task
(no Task<T>
). ¿Hay algo integrado en .NET para hacer esto?
Una pregunta relacionada: Crear una tarea completada <T>
c#
.net
async-await
task-parallel-library
Timothy Shields
fuente
fuente
It seems like the answer I'm getting from everyone is that using a garbage value like this is the correct way. That there isn't a way to do this without the garbage value is disappointing -- oh well.
¿Qué problemas crees que tiene esto? Si almacena un solo caché,Task
todo su programa ocupa un bit adicional de memoria. Eso es nada . Además, uno podría crear una tarea completa sin hacer eso, simplemente no sería mejor.ValueTask
tareas completadas (es decir, valores que ya tiene para que el código sea esencialmente sincrónico), lo que le ahorrará una asignación.Respuestas:
La versión más reciente de .Net (v4.6) está agregando justamente eso, una tarea incorporada .
Esa propiedad se implementa como un singleton sin bloqueo, por lo que casi siempre usaría la misma tarea completada.
fuente
Task.CompletedTask
todavía es interno.Task<T>
es implícitamente convertible aTask
, así que solo obtenga un completadoTask<T>
(conT
cualquier valor) y úselo. Puede usar algo como esto para ocultar el hecho de que un resultado real está allí, en alguna parte.Tenga en cuenta que dado que no estamos exponiendo el resultado, y la tarea siempre se completa, podemos almacenar en caché una sola tarea y reutilizarla.
Si está utilizando .NET 4.0 y no lo tiene
FromResult
, puede crear el suyo usandoTaskCompletionSource
:fuente
Mi método preferido para hacer esto es llamar
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 al llamante". Eso suena como lo que quieres.Actualización: encontré la fuente en la Fuente de referencia de Microsoft ; allí puede ver esa tarea. Cuando todo contiene lo siguiente:
Entonces Task.CompletedTask es de hecho interno, pero se expone llamando a WhenAll () sin argumentos.
fuente
Me gustaría utilizar
Task.Delay(0)
. Internamente, devuelve una instancia en caché de un completadoTask<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 pienses que puedes usar
Task.Yield()
, pero resulta que el resultado de noTask.Yield()
es un subtipo de , mientras que el resultado de es. Esa es una de las diferencias sutiles entre los dos.Task
Task.Delay(0)
fuente
Puede usar Task.FromResult (en .NET 4.5) para devolver un archivo completado
Task<T>
.Si necesita un no genérico
Task
, siempre puede usarTask.FromResult(0)
o similar, ya queTask<T>
es una subclase deTask
.fuente
Para uso .Net 4.6 y superior
Para la versión inferior puedes usar
fuente
return Task.Delay(0);
lugar?Puede usar Nito.AsyncEx.TaskConstants.Completed de una gran biblioteca AsyncEx de Stephen Cleary .
fuente
Qué tal si:
Puede omitir la supresión de advertencia si no le importa.
fuente
async
todavía crea todo el aparato de máquina de estado, incluso si no lo usa, por lo que devolver una tarea vacía es más eficiente para escenarios de bajos recursos.