Czytałem dużo o tym, jak radzić sobie z wyjątkami w TPL, ale tak naprawdę nie rozumiem.wyjątek obsługi w Tpl
Weźmy ten przykładowy kod:
var task1 = new Task(() => { throw new Exception("Throw 1"); });
var task2 = task1.ContinueWith(t => Console.WriteLine("Catch 1:{0}", t.Exception.Message),
TaskContinuationOptions.OnlyOnFaulted);
var task3 = task2.ContinueWith(t => Console.WriteLine("Continuation"));
task1.Start();
try {
task1.Wait();
}
catch (Exception ex) {
Console.WriteLine("Wait Exception: {0}", ex.Message);
}
Spodziewałem się, aby wydrukować
Catch 1
Continuation
Ale pojawia
Catch 1
Continuation
Wait Exception
Oznacza to, że wyjątek jest nadal uważane nieobsługiwany gdy zadanie zostanie zakończone, a finalizator zadań ostatecznie zniszczy aplikację.
Jak obsłużyć wyjątek w ramach kontynuacji, aby finalizator nie rzucił? W tym samym czasie chcę, aby zadanie pozostało w stanie błędu, więc zawijanie zadania w trybie prób/catch nie będzie działać.
Tło jest, że chcę, aby zaimplementować wzorzec zdarzeń asynchronicznej zgodnie here ale z obsługi błędów. Mój pełny kod wygląda następująco
public IAsyncResult Begin(AsyncCallback callback, object state, Action action) {
var task1 = new Task(action);
var task2 = task1.ContinueWith(t => HandleException(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
if (callback != null) {
var task3 = task2.ContinueWith(t => callback(t),
TaskScheduler.FromCurrentSynchronizationContext());
var task4 = task3.ContinueWith(t => HandleException(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
}
task1.Start();
return task;
}
Myślałem o wywołaniu 't.Wait()' w próbie kontynuacji i ignorowaniu wyjątku. Ale to nie zadziała, ponieważ kontynuacja może być wykonana po innych rzutach 'Wait()'. – svick