ASP .NET Core - Posso eliminar o uso do async/await ?
Hoje vamos discutir sobre a possibilidade de eliminar o uso do async/await na ASP .NET Core. |
Você já deve saber que o uso da programação assíncrona (leia-se async/await) na plataforma .NET não tem como objetivo aumentar o desempenho, mas esta relacionada em aumentar a quantidade de requests que podem ser tratados ao mesmo tempo usando os mesmos recursos.
Desta forma a programação assíncrona faz apenas uma coisa : Se uma tarefa está sendo aguardada e essa tarefa não envolve trabalho vinculado à CPU e, como resultado, a thread fica ociosa, então, essa thread pode ser liberada para retornar ao pool de threads para fazer outro trabalho.
Quando você usa async/await em seu código para tratar com a programação assíncrona o objetivo é usar os recursos com mais eficiência, e isso esta relacionada com operações de I/O (input/output) e não operações vinculadas a CPU.
Isso nos leva a pensar da seguinte forma :
Então não devemos usar async e await ???
Não é esta a conclusão que você deve chegar.
Se hoje você considerar que o uso da programação assíncrona não vai lhe trazer os benefícios esperados quem garante que no futuro isso não vai mudar ?
Agora imagine você ter que refatorar o seu código adequando-o à programação assíncrona no futuro !!!
O custo de desempenho da programação assíncrona geralmente é insignificante e, se você precisar dela, isso salvará a sua aplicação.
Posso eliminar o uso de async/await
Outro ponto de discussão que ainda existe é a possibilidade de eliminar o uso do async/await em certos cenários devido ao custo envolvido com sua utilização.
Considere o seguinte exemplo:
public async Task ExemploAsync(int id)
{
return await MetodoExemploAsync();
}
|
Aqui temos o trio dinâmico em ação : async, await e Task
Estamos retornando um Task que é aguardada (waited) e desembrulhada, e a seguir uma nova Task é criada para retornar de MetodoExemploAsync()
Como isso tem um custo que tal se escrevermos o código eliminando o async e o await:
public Task ExemploAsync(int id)
{
return MetodoExemploAsync();
}
|
Agora o Task retornado por MetodoExemploAsync é retornado diretamente por ExemploAsync e isso pode reduzir o overhead do uso de async/await.
A argumentação a favor desta abordagem pode afirmar que :
"É mais eficiente eliminar o async e await, pois ao não incluir essas palavras-chave, o compilador pode pular a geração da máquina de estado assíncrona. Isso significa que há menos tipos gerados pelo compilador em seu assembly, menos pressão no coletor de lixo e menos instruções da CPU para executar."
Acontece que cada um desses ganhos é absolutamente mínimo. Há um tipo a menos, um punhado de pequenos objetos salvos do GC(Garbage Collector) e apenas algumas instruções da CPU ignoradas. Na grande maioria das vezes, o uso do assíncrono está lidando com E/S, o que diminui completamente qualquer ganho de desempenho.
Assim na maioria dos cenários, eliminar o uso de async/await não faz nenhuma diferença no tempo de execução de seu aplicativo, e mesmo que a não utilização de async e await possa evitar as modificações do compilador em seu método, isso também significa que todas as modificações do compilador em seu método agora devem ser feitas manualmente se você deseja a mesma semântica.
Outra problema em eliminar o async/await é o tratamento de exceções. A máquina de estado para métodos assíncronos irá capturar exceções de seu código e colocá-las na Task retornada. Sem o uso da palavra-chave async, a exceção será gerada diretamente, em vez de prosseguir na tarefa.
Assim a recomendação é continuar usando async/await mesmo que no momento você tenha certeza de que isso não vai te trazer os benefícios esperados.
E estamos conversados...
"(Disse Jesus) Eu sou a videira verdadeira, e meu Pai é
o agricultor.
Todo ramo que, estando em mim, não der fruto, ele o corta; e todo o que dá fruto
limpa, para que produza mais fruto ainda."
João 15:1,2
Referências: