run parallel net library example continuewith async asp c# wpf exception task task-parallel-library

parallel - task result c#



La(s) excepción(es) de una Tarea no se observaron al Esperar en la Tarea o al acceder a su propiedad de Excepción. Como resultado, la excepción no observada fue (3)

Por supuesto; significa que se finalizó una Task después de dejarla en la recolección de basura, pero la tarea en sí falló. Hay dos soluciones:

  • manejar las tareas fallan directamente (use ContinueWith(...) para suscribirse, y marque .IsFaulted y .Exception en la Task en el parámetro)
  • manejar el evento TaskScheduler.UnobservedTaskException y marcarlo observado (llamar a e.SetObserved() después de registrar el error)

¿Qué significa esto y cómo resolverlo?

Estoy usando tareas TPL.

Todo el error

La (s) excepción (es) de una Tarea no se observaron al Esperar en la Tarea o al acceder a su propiedad de Excepción. Como resultado, la excepción no observada se volvió a lanzar por el hilo del finalizador.

en System.Threading.Tasks.TaskExceptionHolder.Finalize ()

mscorlib


Prueba este:

public static void ThrowFirstExceptionIfHappens(this Task task) { task.ContinueWith(t => { var aggException = t.Exception.Flatten(); foreach (var exception in aggException.InnerExceptions) { throw exception; // throw only first, search for solution } }, TaskContinuationOptions.OnlyOnFaulted); // not valid for multi task continuations } public static Task CreateHandledTask(Action action) { Task tsk = Task.Factory.StartNew(action); tsk.ThrowFirstExceptionIfHappens(); return tsk; }


Si crea una Tarea, y nunca llama a la task.Wait() o intente recuperar el resultado de una Task<T> , cuando el recolector de basura recoja la tarea, ésta la derribará durante la finalización. Para obtener más información, consulte la página de MSDN sobre Exception Handling en el TPL .

La mejor opción aquí es "manejar" la excepción. Esto se puede hacer a través de una continuación: puede adjuntar una continuación a la tarea y registrar / tragar / etc. la excepción que ocurra. Esto proporciona una forma limpia de registrar excepciones de tareas, y se puede escribir como un método de extensión simple, es decir:

public static void LogExceptions(this Task task) { task.ContinueWith( t => { var aggException = t.Exception.Flatten(); foreach(var exception in aggException.InnerExceptions) LogException(exception); }, TaskContinuationOptions.OnlyOnFaulted); }

Con lo anterior, puede evitar que cualquier tarea cierre la aplicación y la inicie, a través de:

Task.Factory.StartNew( () => { // Do your work... }).LogExceptions();

Alternativamente, puede suscribirse a TaskScheduler.UnobservedTaskException y manejarlo allí.