Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базовые технологии платформы .NET.docx
Скачиваний:
15
Добавлен:
02.11.2018
Размер:
626.37 Кб
Скачать

Обработка исключений и отмена выполнения задач

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

В библиотеке параллельных расширений используются следующие принципы работы с исключительными ситуациями:

  • При возникновении исключения в задаче (как созданной явно, так и порожденной неявно, например, методом Parallel.For()) это исключение обрабатывается средствами библиотеки (если перехват не был предусмотрен программистом) и перенаправляется в ту задачу, которая ожидает завершения данной;

  • При параллельном возникновении нескольких исключений все они собираются в единое исключение System.AggregateException, которое переправляется дальше по цепочке вызовов задач;

  • Если возникла в точности одна исключительная ситуация, то на её основе будет создан объект AggregateException в целях единообразной обработки всех исключительных ситуаций.

Исключительные ситуации типа AggregateException могут возникать при работе со следующими конструкциями библиотеки параллельных расширений:

  1. Класс Task ‑ исключения, возникшие в теле задачи, будут повторно возбуждены в месте вызова метода Wait() данной задачи. Кроме того, исключение доступно через свойство Exception объекта Task.

  2. Класс Task<T> ‑ исключения, возникшие в теле задачи, будут повторно возбуждены в месте вызова метода Wait() или в месте обращения к экземплярному свойству Task<T>.Result.

  3. Класс Parallel ‑ исключения могут возникнуть в параллельно исполняемых итерациях циклов Parallel.For() и Parallel.ForEach() или в параллельных блоках кода при работе с Parallel.Invoke().

  4. PLINQ ‑ из-за отложенного характера исполнения запросов PLINQ, исключения обычно возникают на этапе перебора элементов, полученных по запросу.

В библиотеке параллельных расширений применяется особый подход для выполнения отмены задач. Отметим, что многие методы задач, упоминавшиеся выше, принимают в качестве аргумент значение типа CancellationToken. Это так называемый токен отмены – своеобразный маркер того, что задачу можно отменить. Класс System.Threading.CancellationTokenSource содержит свойство Token для получения токенов отмены и метод Cancel() для отмены выполнения всех задач, использующих общий токен.

В следующем фрагменте кода демонстрируется типичный сценарий использования токенов отмены: вначале создаётся объект CancellationToken, затем его токен назначается задачам, а потом вызывается метод Cancel(), прерывающий выполнение задач:

var ct = new CancellationTokenSource();

var task = new Task(work, ct.Token);

task.Start();

Task.Factory.StartNew(() =>

{

Thread.Sleep(2000);

Console.WriteLine("Done");

}, ct.Token);

ct.Cancel(); // в нужный момент отменяем обе задачи