2011-10-25 4 views
7

http://msdn.microsoft.com/en-us/library/dd997415.aspxTPL Gestion des exceptions

par l'article mentionné ci-dessus, je suis en train de gérer les exceptions dans une tâche de continuatin. L'exemple je cite dans l'article ci-dessus est la suivante:

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); 

Mon code est:

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

En startTask, je jette une erreur comme l'exemple. Mon attente est que CloseDialog s'exécutera et je peux examiner taskException au sein de cette méthode comme indiqué par l'exemple. Cependant, lorsque je lance l'exception, le code s'arrête simplement avec une exception non gérée. Devrais-je utiliser un bloc try/catch? Si oui, où? Par ailleurs, je veux que ma tâche de continuation (CloseDialog) soit toujours exécutée. J'utilise juste .OnlyOnFaulted parce que c'est ce qui est montré dans l'exemple.

Répondre

10

Une continuation peut savoir si une exception a été levée par l'antécédent Task par la propriété d'exception de la tâche antécédente. Les impressions ci-dessous les résultats d'une NullReferenceException à la console

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

Si task1 déclenche une exception et cette exception n'est pas capturé/interrogé par la suite il est considéré comme non prise en charge et l'application meurt. Avec continuations il suffit d'établir le résultat de la tâche via le Status mot-clé

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 vous n'utilisez pas continuations vous devez soit attendre la tâche dans un try/catch bloc ou interroger une tâche de Result dans un try/catch bloc

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); 
} 

espoir cette aide, même si elle est un peu en retard et vous savez tout ce qu'il ya maintenant! :]