2011-10-25 16 views
7

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

Per l'articolo di cui sopra ho Eccezione sto cercando di gestire le eccezioni in un compito continuatin. L'esempio cito in questo articolo di cui sopra è questo:

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

Il mio codice è:

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

In startTask, butto un errore, proprio come l'esempio. La mia aspettativa è che CloseDialog venga eseguito e che io possa esaminare task.Exception all'interno di quel metodo come mostrato nell'esempio. Tuttavia, quando lancio l'eccezione, il codice si arresta semplicemente con un'eccezione non gestita. Dovrei usare un blocco try/catch? Se sì, dove? A proposito, voglio che il mio task di continuazione (CloseDialog) venga eseguito SEMPRE. Sto solo usando .OnlyOnFaulted perché è quello che viene mostrato nell'esempio.

risposta

10

Una continuazione può scoprire se un'eccezione è stata generata dall'antecedente Task dalla proprietà di eccezione dell'attività antecedente. Il seguente stampa i risultati di un NullReferenceException alla console

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

Se task1 genera un'eccezione e questa eccezione non viene catturata/interrogato dalla prosecuzione è considerato non gestita e l'applicazione muore. Con continuazioni è sufficiente per stabilire il risultato del compito tramite la parola 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; 
    } 
} 

Se non si utilizza continuazioni hai aspettare il compito in un blocco try/catch o interrogare un compito di Result in un try/catch blocco

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

Spero che questo aiuto anche se è un po 'tardi e si sa tutto quello che c'è da ora! :]