Saltar al contenido

Excepciones no controladas de tareas

No dejes de compartir nuestra página y códigos en tus redes sociales, ayúdanos a hacer crecer nuestra comunidad.

Solución:

Estás describiendo el comportamiento tal como era. en .NET 4, pero le resultará difícil forzar la recolección de elementos no utilizados y observar ese comportamiento. La siguiente cita del excelente artículo de Stephen Toub sobre el tema debería dejarlo aún más claro:

Las tareas realizan un seguimiento de si se ha “observado” una excepción no controlada. En este contexto, “observado” significa que el código se ha unido a la Tarea de alguna manera para al menos ser consciente de la excepción. Esto podría ser llamar a Wait/WaitAll en la tarea. Podría estar verificando la propiedad de excepción de la tarea después de que la tarea se haya completado. O podría estar usando la propiedad Resultado de una tarea. Si una Tarea ve que su excepción ha sido observada de alguna manera, la vida es buena. Sin embargo, si se eliminan todas las referencias a una tarea (lo que hace que la tarea esté disponible para la recolección de elementos no utilizados) y si aún no se ha observado su excepción, la tarea sabe que su excepción nunca se observará. En tal caso, la tarea aprovecha la finalización y usa un objeto auxiliar para propagar la excepción no controlada en el subproceso del finalizador. Con el comportamiento descrito anteriormente, esa excepción en el subproceso del finalizador no se controlará e invocará la lógica de excepción no controlada predeterminada, que es registrar el problema y bloquear el proceso.

También sugirió dos métodos de extensión útiles para manejar excepciones en tareas de “disparar y olvidar”: uno ignora la excepción y el otro bloquea inmediatamente el proceso:

public static Task IgnoreExceptions(this Task task)

        TaskContinuationOptions.DetachedFromParent);
    return task;


public static Task FailFastOnException(this Task task)

        TaskContinuationOptions.ExecuteSynchronously 

En .NET 4.5 el comportamiento predeterminado ha cambiado. Nuevamente, una cita de otra publicación de Stephen Toub sobre el tema (gracias a mike z por llamar mi atención en los comentarios):

Para facilitar a los desarrolladores la escritura de código asíncrono basado en tareas, .NET 4.5 cambia el comportamiento de excepción predeterminado para las excepciones no observadas. Si bien las excepciones no observadas seguirán provocando que se genere el evento UnbservedTaskException (no hacerlo sería un cambio importante), el proceso no se bloqueará de forma predeterminada. Más bien, la excepción terminará siendo devorada después de que se genere el evento, independientemente de si un controlador de eventos observa la excepción. Sin embargo, este comportamiento se puede configurar.

Tenga en cuenta que el código anterior no es del todo correcto. Debe devolver el puntero a la task.ContinueWithno la tarea pasada:

public static Task IgnoreExceptions(this Task task)

        TaskContinuationOptions.ExecuteSynchronously);
    return t;

EDITAR:

Esto es un desafío porque depende de cómo encadene sus llamadas. Por ejemplo, la siguiente llamada no funciona como yo esperaría:

public Task MyServiceCall()

  return Task.Run(() => DoSomething()).IgnoreExceptions();

De hecho, este método arroja excepciones porque la respuesta aceptada devuelve la tarea inicial (no la que observa la excepción). Esto podría ser problemático con otras llamadas, como .Wait, .WhenAll etc Uno podría pensar que la tarea nunca tirará, pero puede.

Sin embargo, mi cambio sugerido rompería lo siguiente:

public void SomeMethod()

  var myTask = new Task(() => ...);
  myTask.IgnoreExceptions().Start();

Internamente, hemos decidido dejar obsoleto este método de extensión porque es demasiado confuso.

Si te ha resultado provechoso nuestro artículo, sería de mucha ayuda si lo compartes con más desarrolladores y nos ayudes a extender esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *