Quero criar um arquivo concluído Task
(nãoTask<T>
). Existe algo embutido no .NET para fazer isso?
Uma pergunta relacionada: Crie uma tarefa concluída <T>
c#
.net
async-await
task-parallel-library
Timothy Shields
fonte
fonte
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.
Que problemas você acha que isso tem? Se você armazenar em cache um únicoTask
, todo o seu programa ocupará um pouco mais de memória. Isso não é nada . Além disso, pode-se criar uma tarefa concluída sem fazer isso, simplesmente não seria melhor.ValueTask
tarefas concluídas (ou seja, valores que você já possui para que o código seja essencialmente síncrono), o que salvará uma alocação.Respostas:
A versão mais recente do .Net (v4.6) está adicionando exatamente isso, um Task.CompletedTask interno :
Essa propriedade é implementada como um singleton sem bloqueio, então você quase sempre usaria a mesma tarefa concluída.
fonte
Task.CompletedTask
ainda é interno.Task<T>
é implicitamente conversível emTask
, portanto, basta obter um preenchimentoTask<T>
(com todoT
e qualquer valor) e usá-lo. Você pode usar algo assim para ocultar o fato de que um resultado real existe, em algum lugar.Observe que, como não estamos expondo o resultado e a tarefa está sempre concluída, podemos armazenar em cache uma única tarefa e reutilizá-la.
Se você estiver usando o .NET 4.0 e não o tiver
FromResult
, poderá criar seu próprio usandoTaskCompletionSource
:fonte
Meu método preferido para fazer isso é chamar
Task.WhenAll()
sem argumentos. A documentação do MSDN informa que "Se o array / enumerável fornecido não contiver tarefas, a tarefa retornada fará a transição imediatamente para um estado RanToCompletion antes de retornar ao chamador". Parece o que você quer.Atualização: Encontrei a fonte na Fonte de Referência da Microsoft ; lá você pode ver que Task.WhenAll contém o seguinte:
Portanto, Task.CompletedTask é realmente interno, mas é exposto chamando WhenAll () sem argumentos.
fonte
Eu usaria
Task.Delay(0)
. Internamente, ele retorna uma instância em cache de uma conclusãoTask<T>
. É exatamente o que a resposta atual sugere que seja feita, mas agora você não precisa armazenar em cache uma instância por conta própria nem possui valores de lixo deselegantes em seu código.Você pode estar pensando que pode usar
Task.Yield()
, mas o resultado de nãoTask.Yield()
é um subtipo de , enquanto o resultado de é. Essa é uma das diferenças sutis entre os dois.Task
Task.Delay(0)
fonte
Você pode usar Task.FromResult (no .NET 4.5) para retornar um resultado concluído
Task<T>
.Se você precisar de um não genérico
Task
, poderá sempre usarTask.FromResult(0)
ou semelhante, poisTask<T>
é uma subclasse deTask
.fonte
Para o uso do .Net 4.6 e superior
Para a versão inferior, você pode usar
fonte
return Task.Delay(0);
?Você pode usar o Nito.AsyncEx.TaskConstants.Completed de uma excelente biblioteca AsyncEx de Stephen Cleary .
fonte
E se:
Você pode deixar de fora a supressão de aviso se não se importar.
fonte
async
ainda cria todo o aparelho da máquina de estado, mesmo que você não o utilize, portanto, retornar uma tarefa vazia é mais eficiente para cenários de baixo recurso.