¿Debo evitar los controladores de eventos ‘async void’?

Sé que generalmente se considera una mala idea utilizar los métodos async void y olvidar para comenzar las tareas, porque no hay una pista de la tarea pendiente y es complicado manejar las excepciones que podrían arrojarse dentro de dicho método.

¿Debo evitar generalmente los controladores de eventos async void también? Por ejemplo,

 private async void Form_Load(object sender, System.EventArgs e) { await Task.Delay(2000); // do async work // ... } 

Puedo reescribirlo así:

 Task onFormLoadTask = null; // track the task, can implement cancellation private void Form_Load(object sender, System.EventArgs e) { this.onFormLoadTask = OnFormLoadTaskAsync(sender, e); } private async Task OnFormLoadTaskAsync(object sender, System.EventArgs e) { await Task.Delay(2000); // do async work // ... } 

¿Cuáles son las rocas submarinas para los controladores de eventos asíncronos, además de una posible reincorporación?

La guía es para evitar el async void excepto cuando se utiliza en un controlador de eventos, por lo que el uso de un async void en un controlador de eventos está bien.

Dicho esto, por razones de pruebas unitarias a menudo me gusta restar importancia a la lógica de todos los métodos de async void . P.ej,

 public async Task OnFormLoadAsync(object sender, EventArgs e) { await Task.Delay(2000); ... } private async void Form_Load(object sender, EventArgs e) { await OnFormLoadAsync(sender, e); } 

¿Debo evitar generalmente los controladores de eventos async void también?

En general, los controladores de eventos son el único caso en el que un método asíncrono vacío no es un olor de código potencial.

Ahora, si necesita seguir la tarea por algún motivo, la técnica que describe es perfectamente razonable.

Sí, por lo general, el único caso es el vacío asincrónico de los manejadores de eventos. Si quieres saber más sobre esto, puedes ver un excelente video aquí en el canal 9

The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task".

aquí está el enlace

Si usa ReSharper, una extensión gratuita recomendada podría ser útil para usted. Analiza los métodos de “vacío asíncrono” y destaca cuando se usa de manera inapropiada. La extensión puede distinguir diferentes usos de async void y proporcionar soluciones rápidas apropiadas descritas aquí: ReCommended-Extension wiki .