2011-10-25 16 views
7

http://msdn.microsoft.com/en-us/library/dd997415.aspxTPL manejo

por el artículo de referencia por encima de lo Excepción estoy tratando de controlar las excepciones en una tarea continuatin. El ejemplo que cito en el artículo anterior es la siguiente:

var task1 = Task.Factory.StartNew(() => 
{ 
    throw new MyCustomException("Task1 faulted."); 
}) 
.ContinueWith((t) => 
    { 
     Console.WriteLine("I have observed a {0}", 
      t.Exception.InnerException.GetType().Name); 
    }, 
    TaskContinuationOptions.OnlyOnFaulted); 

Mi código es:

Task<string> task = Task<string>.Factory.StartNew(() => process.StartTask(this)); 
task.ContinueWith(CloseDialog, TaskContinuationOptions.OnlyOnFaulted); 

En startTask, lanzo un error al igual que el ejemplo. Mi expectativa es que CloseDialog se ejecutará y puedo examinar task.Exception dentro de ese método como se muestra en el ejemplo. Sin embargo, cuando lanzo la excepción, el código simplemente se detiene con una excepción no controlada. ¿Debo usar un bloque de prueba/captura? ¿Si es así, donde? Por cierto, quiero que mi tarea de continuación (CloseDialog) se ejecute SIEMPRE. Solo estoy usando .OnlyOnFaulted porque eso es lo que se muestra en el ejemplo.

Respuesta

10

Una continuación puede averiguar si una excepción fue arrojada por el antecedente Task por la propiedad de excepción de la tarea antecedente. El siguiente imprime los resultados de un NullReferenceException a la consola

Task task1 = Task.Factory.StartNew (() => { throw null; }); 
Task task2 = task1.ContinueWith (ant => Console.Write(ant.Exception()); 

Si task1 lanza una excepción y esta excepción no se captura/consultada por la continuación se considera no controlada y la aplicación muere. Con continuaciones es suficiente para establecer el resultado de la tarea a través de la palabra clave Status

asyncTask.ContinueWith(task => 
{ 
    // Check task status. 
    switch (task.Status) 
    { 
     // Handle any exceptions to prevent UnobservedTaskException.    
     case TaskStatus.RanToCompletion: 
      if (asyncTask.Result) 
      { 
       // Do stuff... 
      } 
      break; 
     case TaskStatus.Faulted: 
      if (task.Exception != null) 
       mainForm.progressRightLabelText = task.Exception.InnerException.Message; 
      else 
       mainForm.progressRightLabelText = "Operation failed!"; 
     default: 
      break; 
    } 
} 

Si no se utiliza continuaciones que o bien tienen que esperar en la tarea en un bloque try/catch o consultar una en la tarea de Result un try/catch bloque

int x = 0; 
Task<int> task = Task.Factory.StartNew (() => 7/x); 
try 
{ 
    task.Wait(); 
    // OR. 
    int result = task.Result; 
} 
catch (AggregateException aggEx) 
{ 
    Console.WriteLine(aggEx.InnerException.Message); 
} 

esperanza esta ayuda, incluso si es un poco tarde y sabes todo lo que hay por ahora! :]