Wszystko, jest wiele pytań na powyższy temat, ale uważam, że jest wystarczająco odmienny, aby uzasadnić nowe pytanie. Mam następujące Task
i kontynuację do czynienia z różnych zadań Status
; TaskStatus.RanToCompletion
, TaskStatus.Canceled
i oczywiście AggregateException
przez TaskStatus.Faulted
. Kod wyglądaObsługa licencji TPL i wyjątków
Task<bool> asyncTask = Task.Factory.StartNew<bool>(() =>
asyncMethod(uiScheduler, token, someBoolean), token);
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;
}
}
To wszystko działa dobrze, ale obawiam się, czy nie robię z tego prawa, ponieważ istnieje możliwość nastąpienia AggregateException
wyrzucane z wnętrza kontynuacji - co wtedy?
Nie chcę Wait
na moim asyncTask
ani kontynuacji, ponieważ spowoduje to zablokowanie powrotu do wątku interfejsu użytkownika. Aby wychwycić wszystkie wyjątki generowane od wewnątrz kontynuacji nie znaczy, że muszę zrobić coś takiego na pewno
Task parentTask = Task.Factory.startNew(() =>
{
Task<bool> asyncTask = Task.Factory.StartNew<bool>(() =>
asyncMethod(uiScheduler, token, someBoolean), token);
Task continueTask = asyncTask.ContinueWith(task =>
{
// My continuation stuff...
}
try
{
continueTask.Wait();
}
catch(AggregateException aggEx)
{
// Some handling here...
}
});
byłoby to jeszcze działa? Jaka jest tutaj najlepsza praktyka?
Jak zawsze, dziękuję za poświęcony czas.
Widziałem zadania, które "biegły do końca", gdy w rzeczywistości rzuciły wyjątek AggregateException. Ten rodzaj obsługi błędów nie działa. Dlaczego po prostu nie użyć funkcji "próbuj/złap"? –
Masz na myśli metodę, która jest wywoływana w wątku tła lub w rzeczywistej metodzie delegowania kontynuacji? – MoonKnight