Zwykle dla kodu, w którym nie oczekuję wyjątków, ale robi (tj. Błąd programowania), chcę, aby aplikacja uległa awarii (aby "uszkodzone dane, zgłosić nieprawidłowe dane użytkownikowi itp.".Uzyskiwanie nieoczekiwanego zadania Wyjątek w celu usunięcia aplikacji wcześniej niż zbieranie śmieci
Czy istnieje dobra praktyka uzyskiwania (bliższe) tego zachowania podczas korzystania z Tasks
? Zarejestrowaliśmy program obsługi dla TaskScheduler.UnobservedTaskException
. Problem polega na tym, że może się to zdarzyć później, niż później, powodując nieoczekiwany wyjątek.
Pytanie: Która opcja należy używać jeśli:
Mam owinąć moje działanie
Task
s w try/catch i eskalować w połowu wyjątków nie oczekuję? A jeśli tak, to co należy zrobić, aby eskalować (tj Chciałbym aby zmusić go do ognia zdarzenieAppDomain.UnhandledException
i zakończyć.powinienem dołączyć kontynuację (
OnlyOnFaulted
) na wątku UI (jest to aplikacja WinForm), który ponownie generuje wyjątek, jeśli nie jest oczekiwana wyjątekCzy jest lepszy lub bardziej standardowe podejście
Oto co # 1 może wyglądać tak:?
var t1 = Task.Factory.StartNew(() =>
{
try
{
string path = null; // Programming error. Should have been a valid string. Will cause System.ArgumentNullException below
using (FileStream fs = File.Create(path))
{
}
}
catch (System.IO.IOException) { throw; } // Expected possible exception
catch (System.UnauthorizedAccessException) { throw; }
catch
{
// Anything caught here is not an expected exception and should be escalated.
// But how?
}
});
Oto co # 2 może wyglądać następująco:
TaskScheduler uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
var t1 = Task.Factory.StartNew(() =>
{
string path = null; // Programming error. Should have been a valid string. Will cause System.ArgumentNullException below
using (FileStream fs = File.Create(path))
{
}
});
t1.ContinueWith(t =>
{
Exception ex = t.Exception;
if (ex is IOException || ex is UnauthorizedAccessException) // Expected exceptions (do nothing)
return;
throw ex; // Not expected (escalate by rethrowing)
}, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiTaskScheduler);