Mejores prácticas
En esta página
Evite el vacío asíncrono
-
El único lugar donde puede usar
async void
de forma segura es en los controladores de eventos. Considere el siguiente código:private async Task<bool> SomeFuncAsync() { ... await ... } public void button1_Click(object sender, EventArgs e) { var result = SomeFuncAsync().Result; SomeOtherFunc(); }
Una vez que se completa la llamada async
, espera a que SynchronizationContext
esté disponible. Sin embargo, el controlador de eventos conserva SynchronizationContext
mientras espera que se complete el método SomeFuncAsync
; provocando así una espera circular (interbloqueo).
Para solucionar esto, necesitamos modificar el controlador de eventos para:
public async void button1_Click(object sender, EventArgs e) {
var result = await SomeFuncAsync();
SomeOtherFunc();
}
-
Cualquier excepción arrojada por un método
async void
se generará directamente en elSynchronizationContext
que estaba activo cuando se inició el métodoasync void
.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
. -
Los métodos
async void
no proporcionan una manera fácil de notificar al código de llamada que han completado -
Los métodos
async void
son difíciles de probar. La compatibilidad con pruebas asincrónicas de MSTest solo funciona para los métodosasincrónicos
que devuelvenTask
oTask<T>
.