O artigo do MSDN intitulado "Melhores Práticas da Programação Assíncrona (Best Practices in Asynchronous Programming)" apresenta algumas considerações interessantes:
- De preferência as tarefas async sobre métodos async sem valor de retorno (aqueles que retornam void). Isso não se aplica para tratamento de eventos. Keith Patton da Marker Metro também explica isso em detalhes;
- Evite misturar código síncrono com assíncrono porque pode causar um risco maior de deadlocks, tratamento de erros mais complexos e bloqueio inesperado de threads de contexto;
- Use o ConfigureAwait(false) para obter um desempenho melhor se o restante do código não precisa de informações do contexto original, pois o código restante continuará na threadpool do contexto. Isso ajuda a evitar deadlocks nos casos em que é obrigado a misturar código síncrono e assíncrono. Note que isso se aplica de maneira um pouco distinta quando tratamos o código no lado do servidor.
Chris Hurley, engenheiro de software da RedGate, explica o overhead de CPU de async-await e demonstra por meio da analise da execução de um código exemplo:
- A invocação de um método que usa palavra chave "async" necessita da criação de uma máquina de estados e a construção de uma tarefa que contém o trabalho que deve ser executado, dessa forma é obtido o contexto de execução e de sincronização;
- No exemplo analisado, 963 métodos do framework foram executados para inicializar um método async relativamente simples na primeira chamada;
- O contexto é armazenado em cache para que as subsequentes chamadas consumam menos recursos;
- Para os métodos que podem executar assincronamente no período muito curto de tempo, digamos 1 milisegundo, a ativação da chamada assíncrona bloqueia a thread por um período maior do que o necessário para sua computação. No exemplo usado, precisou de mais de 45 ms antes que a thread chamada fosse desbloqueada. Mesmo quando o código está dentro de um laço de repetição, embora as subsequentes chamadas exigissem menos tempo de processamento, a chamada da thread realmente não fornece nenhuma melhoria no desempenho;
- Em resumo, evite uso de async/await para métodos muito curtos ou o uso de await em laços pequenos (coloque o laço inteiro em um método assíncrono).
Em outra notícia também apresentamos algumas outras pegadinhas comuns que ocorrem ao utilizar o async/await.