Обработка исключений TPL - PullRequest
       1

Обработка исключений TPL

7 голосов
/ 26 октября 2011

http://msdn.microsoft.com/en-us/library/dd997415.aspx

Согласно статье, указанной выше, я пытаюсь обработать исключения в продолжающейся задаче.Пример, который я привожу в приведенной выше статье, таков:

var task1 = Task.Factory.StartNew(() =>
{
    throw new MyCustomException("Task1 faulted.");
})
.ContinueWith((t) =>
    {
        Console.WriteLine("I have observed a {0}",
            t.Exception.InnerException.GetType().Name);
    },
    TaskContinuationOptions.OnlyOnFaulted);

Мой код:

Task<string> task = Task<string>.Factory.StartNew(() => process.StartTask(this));
task.ContinueWith(CloseDialog, TaskContinuationOptions.OnlyOnFaulted);

В StartTask я выдаю ошибку, как в примере.Я ожидаю, что CloseDialog будет выполняться, и я могу изучить task.Exception в этом методе, как показано в примере.Однако, когда я выкидываю исключение, код просто останавливается с необработанным исключением.Должен ли я использовать блок try / catch?Если да, то где?Кстати, я хочу, чтобы моя задача продолжения (CloseDialog) ВСЕГДА выполнялась.Я просто использую .OnlyOnFaults, потому что это то, что показано в примере.

1 Ответ

11 голосов
/ 27 марта 2012

Продолжение может определить, было ли исключение выдано антецедентом Task свойством исключения задачи антецедента. Следующее выводит результаты NullReferenceException на консоль

Task task1 = Task.Factory.StartNew (() => { throw null; });
Task task2 = task1.ContinueWith (ant => Console.Write(ant.Exception());

Если task1 выдает исключение, и это исключение не перехватывается / не запрашивается продолжением, оно считается необработанным, и приложение умирает. Для продолжения достаточно установить результат задачи по ключевому слову Status

.
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;
    }
}

Если вы не используете продолжения, вам придется подождать выполнение задачи в блоке try / catch или запросить Result задачи в блоке try / catch

int x = 0;
Task<int> task = Task.Factory.StartNew (() => 7 / x);
try
{
    task.Wait();
    // OR.
    int result = task.Result;
}
catch (AggregateException aggEx)
{
    Console.WriteLine(aggEx.InnerException.Message);
}

Надеюсь, это поможет, даже если уже немного поздно, и вы знаете все, что есть сейчас! :]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...