Como criar um método aguardável corretamente
Estou escrevendo alguns métodos aguardáveis e encontrei muitas maneiras de fazê-lo na internet. Então eu vim aqui para saber o que realmente está acontecendo em cada sentido, e se alguns modos devem ser banidos.
Até onde eu sei, existem dois tipos de métodos aguardáveis:
Aqueles que chamam outros métodos aguardáveis:public async Task<Foo> GetFooAsync()
{
var foo = await TrulyGetFooAsync();
// Do stuff with foo
return foo;
}
Não encontrei outra maneira de fazer isso e acho que é o caminho certo. Diga-me se estou errado!
Aqueles que chamam apenas métodos não aguardáveis:E aqui os problemas vêm à minha mente.
Por exemplo, eu vi isso:
Exemplo 1public async Task<Foo> GetFooAsync()
{
return await Task.Run(() => TrulyGetFoo());
}
Tanto quanto eu entendo, as palavras-chave async / waitit são inúteis e podem ser evitadas para fornecer isso:
Exemplo 2public Task<Foo> GetFooAsync()
{
return Task.Run(() => TrulyGetFoo());
}
Este último exemplo é o que eu estava fazendo até agora. Sobre isso, existe uma diferença entre:
Task.Run(() => TrulyGetFoo());
e
Task.Run((Foo)TrulyGetFoo); // I don't know if the cast is required at any time but in my code, it was
???
Mas recentemente encontrei o seguinte:
Exemplo 3public Task<Foo> GetFooAsync()
{
TaskCompletionSource<Foo> tcs = new TaskCompletionSource<Foo>();
tcs.SetResult(TrulyGetFoo());
return tcs.Task;
}
Se eu entendi corretamente, um método aguardável nem sempre é executado em outro thread ??? Meu palpite é que o terceiro exemplo está fornecendo esse mecanismo (mas como ??? só vejo código síncrono no terceiro exemplo), quando os exemplos 1 e 2 sempre serão executados em um thread de trabalho ???
Pode haver ainda outras maneiras de escrever métodos aguardáveis, então, deixe-me saber sobre eles.