Melhores Práticas
Nesta página
Evite vazio assíncrono
-
O único lugar onde você pode usar
async void
com segurança é em manipuladores de eventos. Considere o seguinte código:private async Task<bool> SomeFuncAsync() { ... await ... } public void button1_Click(object sender, EventArgs e) { var result = SomeFuncAsync().Result; SomeOtherFunc(); }
Assim que a chamada async
for concluída, ela espera que o SynchronizationContext
fique disponível. No entanto, o manipulador de eventos mantém o SynchronizationContext
enquanto aguarda a conclusão do método SomeFuncAsync
; causando assim uma espera circular (deadlock).
Para corrigir isso, precisamos modificar o manipulador de eventos para:
public async void button1_Click(object sender, EventArgs e) {
var result = await SomeFuncAsync();
SomeOtherFunc();
}
-
Qualquer exceção lançada de um método
async void
será gerada diretamente noSynchronizationContext
que estava ativo quando o métodoasync void
foi iniciado.private async void SomeFuncAsync() { throw new InvalidOperationException(); } public void SomeOtherFunc() { try { SomeFuncAsync(); } catch (Exception ex) { Console.WriteLine(ex); throw; } }
the exception is never caught by the catch block in
SomeOtherFunc
. -
Os métodos
async void
não fornecem uma maneira fácil de notificar o código de chamada de que eles foram concluídos -
Métodos
async void
são difíceis de testar. O suporte a testes assíncronos do MSTest funciona apenas para métodosasync
que retornamTask
ouTask<T>
.