11

Existen varias maneras de observar las excepciones lanzadas dentro de las tareas. Uno de ellos es en un ContinueWith con OnlyOnFaulted:Observación de excepciones de tareas dentro de un ContinuarCon

var task = Task.Factory.StartNew(() => 
{ 
    // Throws an exception 
    // (possibly from within another task spawned from within this task) 
}); 

var failureTask = task.ContinueWith((t) => 
{ 
    // Flatten and loop (since there could have been multiple tasks) 
    foreach (var ex in t.Exception.Flatten().InnerExceptions) 
     Console.WriteLine(ex.Message); 
}, TaskContinuationOptions.OnlyOnFaulted); 

Mi pregunta: ¿Las excepciones se convierten observaron de forma automática una vez que comienza failureTask O es que sólo llegan a ser observada una vez que 'toque' ex.Message?

+1

¿Qué quiere decir por observado? Su delegado de ContinueWith solo se llamará una vez, si eso es lo que quiere decir, independientemente de si accede al objeto de excepción o no. –

+0

Quizás él quiere decir "¿volverá a lanzar la excepción si simplemente llamo a' OnlyOnFaulted' independientemente de tener acceso a 't.Exceptions'"? – user7116

+0

Si no "observa" las excepciones (esta es la terminología de Microsoft) lanzadas desde Tareas, entonces el recolector de basura las arrojará en un momento posterior. Mi delegado de ContinueWith seguramente podría ser llamado varias veces (si varias tareas desde mi tarea principal arrojan excepciones) ... ¿o podría llamarse con un árbol AggregateException con todas las excepciones arrojadas? – davenewza

Respuesta

10

Se ven como observado una vez que acceda a la propiedad Exception.

Véase también AggregateException.Handle. Se puede utilizar en lugar t.Exception.Handle:

t.Exception.Handle(exception => 
      { 
      Console.WriteLine(exception); 
      return true; 
      } 
    ); 
+0

Gracias. Parece que hay muchas formas de manejar excepciones de tareas. – davenewza

+1

Sí, prefiero el método Handle; porque es más explícito. Pero, podría no ser útil en todas las circunstancias. –

2

muestra

Task.Factory.StartNew(testMethod).ContinueWith(p => 
      { 
       if (p.Exception != null) 
        p.Exception.Handle(x => 
         { 
          Console.WriteLine(x.Message); 
          return false; 
         }); 
      }); 
+2

¿No debería el predicado transferido a la función Handle() aquí devolver true si desea marcar las excepciones tal como se manejaron (como la respuesta anterior anterior)? Supongo que depende de lo que quieras hacer, pero supongo que queremos marcar la excepción como manejada. –

Cuestiones relacionadas