una traves todos thread subprocesos subproceso seguras requiere realizar que para otro metodo los llamó llamar llamadas interfaz función framework formularios form evaluación ejecuten diferente desde controles control como checkforillegalcrossthreadcalls aplicación aplanó acceder c# async-await

c# - traves - realizar llamadas seguras para subprocesos en controles de formularios windows forms



¿Está bien declarar un método async como return void para silenciar la advertencia CS4014? (3)

¿Está bien tener un método ''async void'' si el método no está diseñado para ser aguardable en primer lugar y si no se lanzará ninguna excepción?

Aunque puede ser "correcto" hacerlo, aún así lo alentaría a que realice el método de async Task . A pesar de que está 100% seguro de que este método no se lanzará, y no se espera, nunca se sabe cómo podría terminar usándose. Ahora sabe perfectamente cuáles son las consecuencias de usar el async void , pero si hay una pequeña posibilidad de que alguien necesite usar esto en el futuro, entonces es mejor que haga un buen comentario sobre por qué esta Task no es siendo esperado en lugar de seguir el camino fácil de hacer que este void .

No dejes que las advertencias del compilador te preocupen, diría preocupación por la corrección y los efectos que esto puede tener en tu código base.

Visual Studio emite una advertencia para este código (''porque esta llamada no está esperando, la ejecución del método actual continúa antes de que se complete la llamada'').

static void Main(string[] args) { FireAndForget(); // <-- Warning CS4014 // Do something else. } static async Task FireAndForget() { // Do something (cannot throw). }

Según entiendo, está bien que no espere la tarea en este caso en particular porque FireAndForget nunca arrojará una excepción.

En lugar de deshabilitar la advertencia con un pragma, estaba considerando cambiar el tipo de devolución de FireAndForget de Task to void. Eso efectivamente silencia el compilador.

static async void FireAndForget() // <-- Task changed to void { // Do something (cannot throw). }

Sin embargo, según Stephen Cleary , se deben evitar los métodos ''async void'', así que no estoy seguro de qué hacer.

¿Está bien tener un método ''async void'' si el método no está diseñado para ser aguardable en primer lugar y si no se lanzará ninguna excepción?


Es extremadamente raro tener una verdadera operación de disparar y olvidar; es decir, una operación donde:

  • A nadie le importa cuando se completa.
  • A nadie le importa si se completa.
  • A nadie le importa si arroja una excepción.

Particularmente con el último de estos; la mayoría de las operaciones llamadas "disparar y olvidar" en realidad no son de "olvidar y olvidar" porque es necesario tomar alguna acción si no tiene éxito.

Dicho esto, hay algunas situaciones en las que se puede olvidar y olvidar.

Prefiero usar la async Task y evitar la advertencia del compilador asignando la tarea a una variable que de otro modo no se usaría:

var _ = FireAndForget();

async Task métodos de async Task son más reutilizables y comprobables que los métodos de async void .

Sin embargo, no lanzaría un ataque si un desarrollador de mi equipo acabara de usar un async void .


Un posible problema es que ahora será imposible saber si el código arrojó una excepción o no. Entonces, si tiene pruebas unitarias para detectarlas, las pruebas de la unidad nunca funcionarán.

Ejemplo clásico del sitio de MSDN:

private async void ThrowExceptionAsync() { throw new InvalidOperationException(); } public void AsyncVoidExceptions_CannotBeCaughtByCatch() { try { ThrowExceptionAsync(); } catch (Exception) { // The exception is never caught here! throw; } }

http://haacked.com/archive/2014/11/11/async-void-methods/

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

En lugar de usar el async void , si se trata de un caso de borde específico, ¿qué hay de usar las declaraciones pragma?

#pragma warning disable CS-4014 ... your code here ... #pragma warning restore CS-4014

De esta forma puedes desconectar el ruido estático.

HTH ...