Обработка ошибок в задачах




При ожидании завершения задачи с помощью метода Wait(), или свойства Result, любое необработанное исключение будет передано вызывающему коду, а именно объекту AggregationException, что делает не обязательным обработку исключений внутри самой задачи:

int x = 0;

Task<int> z = Task.Factory.StartNew (() => 10 / x);

try

{

Console.WriteLine (calc.Result);

}

catch (AggregateException aex)

{

Console.Write (aex.InnerException.Message);

}

Но все же необходимо обрабатывать исключения автономных задач (т.е задач, которые не являются родительскими для других задач, и завершения, выполнения которых никто не ожидает).


увеличить изображение
Рис. 7.5. Результат выполнения программы с обработкой исключения

Отмена выполнения задач

Отмена выполнения заданий осуществляется с помощью специальных маркеров отмены (token). Структура CancellationToken - распространяет уведомление о том, что операции следует отменить. При запуске задачи можно передать маркер отмены, что позволит отменить выполнение задачи:

CancellationTokenSource cancelSource = new CancellationTokenSource();

CancellationToken token = cancelSource.Token;

 

Task task = Task.Factory.StartNew (() =>

{

token.ThrowIfCancellationRequested(); // Проверяем запрос отмены

}, token);

...

cancelSource.Cancel();

Для отмененной задачи вызывается исключение - AggregateException, которое необходимо обработать и проверить следующим образом:

try

{

task.Wait();

}

catch (AggregateException ex)

{

if (ex.InnerException is OperationCanceledException)

Console.Write ("Задание отменено");

}


увеличить изображение
Рис. 7.6. Результат выполнения программы с использованием отмены задачи

Продолжения

Для того что бы упорядочить выполнение задач в программе, т.е. к примеру что бы Задача 3 выполнялась сразу же после выполнения Задачи 2, а Задача 2 после завершения Задачи 1, необходимо использовать методContinueWith() класса - Task. Форма объявление данного метода представлена ниже:

public Task ContinueWith(Action<Task>)

Пример работы метода ContinueWith() представлен ниже:

Task task1 = Task.Factory.StartNew (() => Console.Write ("Hello "));

Task task2 = task1.ContinueWith (main => Console.Write ("World!"));

где main - аргумент, который передается в задачу-продолжение в лямбда-выражении, является ссылкой на родительскую задачу.


увеличить изображение
Рис. 7.7. Результат выполнения программы с использование метода ContinueWith()

Продолжения и Task <TResult>

В классе Task<TResult>, также можно использовать продолжение и возвращать некоторые данные, с использованием последовательности вычисления:

Task.Factory.StartNew<int>(() => 10)

.ContinueWith(main => main.Result * 2)

.ContinueWith(main => Math.Sqrt(main.Result))

.ContinueWith(main => Console.WriteLine(main.Result));


увеличить изображение
Рис. 7.8. Результат выполнения программы с использование продолжения в классе Task<TResult>



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-06-11 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: