ПриМеЧание
Если.вы.регистрируете.метод.обратного.вызова,.используя.уже.отмененный.объект.
CancellationTokenSource,.поток,.вызывающий.метод.Register,.активизирует.обратный.
вызов.(вероятно,.через.SynchronizationContext.вызывающего.потока,.если.в.параметре.
useSynchronizationContext.передано.значение.true)
Многократный вызов метода
Register
приводит к многократной же активизации
методов обратного вызова, причем последние могут генерировать необработанное
755
Скоординированная.отмена
исключение. Если вызвать метод
Cancel
объекта
CancellationTokenSource
с па-
раметром
true
, первый же метод обратного вызова, ставший источником необрабо-
танного исключения, остановит выполнение остальных методов обратного вызова,
а исключение будет также сгенерировано методом
Cancel
. Если же передать этому
методу значение
false
, будут вызваны все зарегистрированные методы обратного
вызова. Все появляющиеся при этом необработанные исключения добавляются
в коллекцию. Если после завершения всех методов обратного вызова обнаружива-
ется наличие необработанных исключений, метод
Cancel
генерирует исключение
AggregateException
, свойству
InnerExceptions
которого присваивается коллекция
сгенерированных объектов исключений. При отсутствии необработанных исклю-
чений метод
Cancel
просто возвращает управление.
ВниМание
Невозможно.определить,.с.какой.операцией.связан.тот.или.иной.объект.из.коллекции.
InnerExceptions.исключения.AggregateException .То.есть.вы.фактически.получаете.
только.информацию.о.том,.что.некоторые.операции.выполнены.не.были,.и.по.типу.
исключения.можете.определить,.в.чем.была.причина.такого.поведения .Чтобы.вы-
яснить.местоположение.ошибки,.нужно.исследовать.свойство.StackTrace.объекта.
исключения.и.вручную.проверить.исходный.код
Метод
Register
объекта
CancellationToken
возвращает структуру
Cancellation-
TokenRegistration
, которая выглядит следующим образом:
public struct CancellationTokenRegistration :
IEquatable, IDisposable {
public void Dispose();
// Не показаны GetHashCode, Equals, операторы == и !=
}
Метод
Dispose
позволяет удалить из объекта
CancellationTokenSource
за-
регистрированный обратный вызов, с которым связан данный объект. В ре-
зультате при вызове метода
Cancel
этот обратный вызов игнорируется. Вот
код, демонстрирующий регистрацию двух обратных вызовов с одним объектом
CancellationTokenSource
:
varcts = new CancellationTokenSource();
cts.Token.Register(() => Console.WriteLine("Canceled 1"));
cts.Token.Register(() => Console.WriteLine("Canceled 2"));
// Для проверки отменим его и выполним оба обратных вызова
cts.Cancel();
Вот результат работы такого кода, полученный сразу после вызова метода
Cancel
:
Canceled 2
Canceled 1
756
Do'stlaringiz bilan baham: |