11

Istnieje kilka sposobów na obserwowanie wyjątków zgłaszanych w ramach zadań. Jednym z nich jest w ContinueWith z OnlyOnFaulted:Obserwowanie wyjątków zadań wewnątrz kontynuacji

var task = Task.Factory.StartNew(() => 
{ 
    // Throws an exception 
    // (possibly from within another task spawned from within this task) 
}); 

var failureTask = task.ContinueWith((t) => 
{ 
    // Flatten and loop (since there could have been multiple tasks) 
    foreach (var ex in t.Exception.Flatten().InnerExceptions) 
     Console.WriteLine(ex.Message); 
}, TaskContinuationOptions.OnlyOnFaulted); 

Moje pytanie: Czy wyjątki zostają automatycznie obserwowane po rozpoczęciu failureTask czy też tylko stać obserwowana kiedyś „dotyk” ex.Message?

+1

Co masz na myśli przez przestrzegane? Twój KontynuacjaZ delegatem zostanie wywołany tylko raz, jeśli o to ci chodzi, niezależnie od tego, czy uzyskasz dostęp do obiektu wyjątku, czy nie. –

+0

Być może ma na myśli "czy wyrzuci wyjątek, jeśli po prostu wywołasz' OnlyOnFaulted' bez względu na dostęp do 't.Exceptions'"? – user7116

+0

Jeśli nie "zauważysz" wyjątków (to jest terminologia Microsoft) wyrzuconych z Tasks, wtedy garbage collector rzuci je dla Ciebie w późniejszym czasie. Moja kontynuacja z delegatem na pewno mógł zostać wywołany wiele razy (jeśli wiele zadań z mojego głównego zadania generuje wyjątki) ... lub może zostać wywołany z drzewem AggregateException z wszystkimi zgłaszanymi wyjątkami? – davenewza

Odpowiedz

10

Są one wyświetlane jako zaobserwowane po uzyskaniu dostępu do usługi.

Zobacz także AggregateException.Handle. Można użyć t.Exception.Handle zamiast:

t.Exception.Handle(exception => 
      { 
      Console.WriteLine(exception); 
      return true; 
      } 
    ); 
+0

Dzięki. Wydaje się, że istnieje wiele sposobów obsługi wyjątków zadań. – davenewza

+1

Tak, wolę metodę Handle; ponieważ jest bardziej wyraźny. Ale może nie być użyteczny we wszystkich okolicznościach. –

2

próbka

Task.Factory.StartNew(testMethod).ContinueWith(p => 
      { 
       if (p.Exception != null) 
        p.Exception.Handle(x => 
         { 
          Console.WriteLine(x.Message); 
          return false; 
         }); 
      }); 
+2

Czy ten predykat przekazany do funkcji Handle() nie zwróci true, jeśli chcesz zaznaczyć wyjątki jako obsługiwane (jak poprzednia odpowiedź powyżej)? Przypuszczam, że to zależy od tego, co chcesz zrobić, ale przypuszczam, że chcemy zaznaczyć wyjątek jako obsługiwany. –

Powiązane problemy