Опубликован: 23.01.2013 | Уровень: для всех | Доступ: платный | ВУЗ: Томский политехнический университет
Лекция 6:

Параллелизм задач

Ожидание задач

Возможно, осуществлять ожидание выполнения задач двумя различными способами:

  • С помощью метода Wait(). Один из возможных форматов объявления этого метода представлен ниже:
    public Wait(TimeSpan timeout)

    где timeout - время ожидания в миллисекундах.

  • C помощью обращения к свойству Result (свойство класса Task<TResult>):
    public TResult Result;

Можно также одновременно ожидать завершения нескольких задач с помощью метода Task.WaitAll() который ожидает завершения всех указанных задач и метода Task.WaitAny() который ожидает завершения какой-либо задачи. Форматы объявления этих методов представлены ниже:

Public static void WaitAll(Task[]);
Public static void WaitAny(Task[]);

где Task[] - массив экземпляров класса Task.

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

Вызов метода WaitAny() эквивалентен ожиданию ManualResetEventSlim, который переводится в сигнальное состояние при завершении конкретной задачи.

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

При ожидании завершения задачи с помощью метода 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. Результат выполнения программы с использованием отмены задачи
Владимир Каширин
Владимир Каширин

Вопрос по Курсу: "Параллельное программирование с использованием MS VisualStudia 2010".

При компиляции Самостоятельного задания (одновременная отрисовка прямоугольников, эллипсов и выдача в текст-бокс случайного числа) среда предупреждает: suspend - устаревшая команда; примените monitor, mutex и т.п.

Создаётся впечатление, что Задание создано в более поздней среде, чем VS 2010.

Александр Гаврилов
Александр Гаврилов
Россия
Роман Дмитриев
Роман Дмитриев
Россия, Москва