2011-10-25 12 views
7

http://msdn.microsoft.com/en-us/library/dd997415.aspxTPL obsługi

Per artykule mowa powyżej I Wyjątek staram się obsługiwać wyjątki w zadaniu continuatin. Przykład jestem powołując się w powyższym artykule jest taka:

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

Mój kod to:

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

W StartTask, rzucam błąd tak jak np. Oczekuję, że CloseDialog zostanie wykonany i mogę sprawdzić task.Exception w tej metodzie, jak pokazano w przykładzie. Jednak kiedy wyrzucam wyjątek I kod po prostu zatrzymuje się z nieobsługiwanym wyjątkiem. Czy powinienem używać bloku prób/catch? Jeśli tak, to gdzie? Przy okazji, chcę, aby moje zadanie kontynuacyjne (CloseDialog) działało ZAWSZE. Używam tylko .OnlyOnFaulted, ponieważ jest to pokazane w przykładzie.

Odpowiedz

10

Kontynuacja może sprawdzić, czy wyjątek został zgłoszony przez poprzednika Task przez właściwość wyjątku zadania poprzedzającego. Poniższy drukuje wyniki NullReferenceException do konsoli

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

Jeśli task1 zgłasza wyjątek i wyjątek ten nie jest zrobione/pytani o kontynuacji uważa nieobsługiwany, a aplikacja umiera. Z kontynuacje to wystarczy, aby ustalić wynik zadania poprzez słowa kluczowego 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; 
    } 
} 

Jeśli nie używać kontynuacje trzeba albo czekać na zadaniu w try/catch bloku lub kwerendy zadanie na Result w try/catch blok

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

Nadzieja ta pomoc, nawet jeśli jest to trochę późno i wiesz wszystko tam jest teraz! :]

Powiązane problemy