Jeśli utworzysz zadanie i nigdy nie zadzwonisz task.Wait()
ani nie spróbujesz pobrać wyniku a Task<T>
, gdy zadanie jest zbierane przez moduł odśmiecania pamięci, zburzy to aplikację podczas finalizacji. Aby uzyskać szczegółowe informacje, zobacz stronę MSDN dotyczącą obsługi wyjątków w TPL .
Najlepszą opcją jest „obsłużenie” wyjątku. Można to zrobić poprzez kontynuację - możesz dołączyć kontynuację do zadania i zarejestrować / połknąć / itp. Wyjątek, który wystąpił. Zapewnia to czysty sposób rejestrowania wyjątków zadań i można go zapisać jako prostą metodę rozszerzenia, tj .:
public static void LogExceptions(this Task task)
{
task.ContinueWith( t =>
{
var aggException = t.Exception.Flatten();
foreach(var exception in aggException.InnerExceptions)
LogException(exception);
},
TaskContinuationOptions.OnlyOnFaulted);
}
W ten sposób możesz zapobiec zniszczeniu aplikacji i zarejestrowaniu jej przez jakiekolwiek zadanie poprzez:
Task.Factory.StartNew( () =>
{
// Do your work...
}).LogExceptions();
Alternatywnie możesz zasubskrybować TaskScheduler.UnobservedTaskException i tam go obsłużyć.
Off
użyj statycznej metody pośredniczącej w klasie nazwanej jako wybrane czteroliterowe słowo i używaj jej do kontynuacji typu catch-all. Pomaga zwalczyć stłumioną frustrację wynikającą z tego szczególnego wyjątku..Net 4.0
. Obsługa wyjątków została domyślnie zmieniona,.net 4.5
aby nie zrywać aplikacji . Zobacz więcej w sekcji Obsługa wyjątków zadań w .NET 4.5Pewnie; oznacza to, że
Task
zostało sfinalizowane po pozostawieniu go do czyszczenia pamięci, ale samo zadanie nie powiodło się. Istnieją dwie poprawki:ContinueWith(...)
do subskrybowania i sprawdź.IsFaulted
i.Exception
naTask
parametrze)TaskScheduler.UnobservedTaskException
zdarzenie i oznaczyć je jako obserwowane (wywołaniee.SetObserved()
po zarejestrowaniu błędu)źródło
IsFaulted
, możesz użyćOnlyOnFaulted
opcji kontynuacji i uniknąć ręcznego sprawdzania ...SetObserved
naUnobservedTaskExceptionEventArgs
potrzeby nazywać.Spróbuj tego:
źródło