2011-02-10 10 views
5

Estoy tratando de evitar que una tarea continúe si falla la primera parte.Prevenir la tarea.Continuar con la excepción

Mi código es el que:

Task listener = Task.Factory.StartNew(openConnection).ContinueWith((t) => listenForNumber()); 

    void openConnection() 
    { 
     try 
     { 
      //stuff 
     } 
     catch 
     { 
      //morestuff 
     } 
    } 

    void listenForNumber() 
    { 
     //even more stuff 
    } 

Ahora listenForNuber() no debe ser ejecutada si openConnection() entra en el bloque catch

Probé ContinueWith((t) => listenForNumber(),TaskContinuationOptions.NotOnFaulted);

Pero sin éxito, cualquier ayuda ? :(

Gracias

+3

¿Reanuda o traga la excepción dentro de ese bloque de captura? –

Respuesta

8

TaskContiuationOptions.NotOnFaulted, obviamente, no tendrá ningún efecto a menos que su método ha criticado, es decir, una excepción lanzada durante su ejecución fue controlada.

En el bloque catch, debe volver a emitir la excepción (y preservar el seguimiento de la pila) usando la declaración throw; después de haber realizado su trabajo (quizás algo de limpieza); de lo contrario, la excepción no se lanzará nuevamente, por lo que su método no se considerará como "fallado".

+0

Bien, pero si vuelvo a lanzar la excepción, ¿dónde está el mejor lugar para tragarla (y cómo) para que no obtenga una excepción agregada o una excepción no controlada por el código de usuario? No es necesario volver a manejarlo, ya que todo se ha realizado en el primer bloque catch. – Ekoms

+0

@Ekoms: hasta donde sé, la excepción AggregateException solo se lanza si está accediendo a la propiedad 'Result' de la tarea. Ese debería ser el único lugar donde se puede tragar la excepción, pero primero debe verificar si realmente es la excepción que intenta tragar, y no solo una excepción inesperada. – ShdNx

1

Debe lanzar la excepción en su método de tarea. El TP L no sabe que el método ha fallado, a menos que capte una excepción.

Aún necesitará tener un método de continuación para el caso con fallas. Este podría ser un método simple que registra la excepción.

Si no tiene un método de continuación para la excepción, obtendrá excepciones no controladas en su aplicación cuando su método de tareas arroje una excepción.

2

Cree un asistente de método de extensión.

public static void PropagateExceptions(this Task task) 
{ 
    if (task == null) 
     throw new ArgumentNullException("task"); 
    if (!task.IsCompleted) 
     throw new InvalidOperationException("The task has not completed yet."); 

    if (task.IsFaulted) 
     task.Wait(); 
} 

luego llame al método de extensión PropagateExceptions() antes de ejecutar cualquier código. El método PropagateExceptions() también volverá a aparecer si la tarea fue cancelada.

t1.ContinueWith(t => { 
    t.PropagateExceptions(); 
    listenForNumber(); 
}); 
Cuestiones relacionadas