Отменить асинхронную операцию - PullRequest
2 голосов
/ 01 декабря 2011

Я занимаюсь разработкой библиотеки классов, которая реализует стек протоколов. Там у меня есть асинхронная операция DoSomething, которая реализует IAsyncResult. Пользователь этого метода может использовать BeginDoSomething и EndDoSomething. Пока это довольно распространенная задача.

Теперь у меня есть требование разрешить прерывание асинхронной операции. Я могу придумать несколько способов добиться этого, но я не уверен, какой из них лучший:

  1. Имеют метод CancelDoSomething, кроме BeginDoSomething и EndDoSomething. Это не обычный шаблон asaync, и поэтому его нелегко найти пользователю операции.
  2. Согласно № 1: Имейте свойство Отмена
  3. Экземпляр IAsyncResult, который возвращается BeginDoSomething, может быть преобразован в DoSomethingAsyncResult. DoSomethingAsyncResult имеет метод Cancel. Опять же, это не обычное использование асинхронного шаблона и вряд ли известно «обычному пользователю» библиотеки классов.
  4. Согласно № 3: Имейте свойство Отмена
  5. Экземпляр IAsyncResult, возвращаемый BeginDoSomething, реализует IAbortableAsyncResult: public IAbortableAsyncResult:IAsyncResult { void Abort(); }. Для меня это, кажется, самый элегантный способ. Когда пользователь запускает операцию, используя BeginDoSomething, он получает экземпляр IAbortableAsyncResult, что означает, что эта специальная функция ему заметно представлена.

Какое лучшее решение? Есть ли еще способы решить эту проблему? Я предпочитаю нет. 5 потому что у него нет запаха кода (по крайней мере, я не узнал до сих пор).

[EDIT]

Подход, не основанный на TPL / .NET 4, приветствуется тем, что имеет решение, которое также применимо в устаревшем коде, который нельзя перенести в последнюю версию .NET Framework.

[/ EDIT]

1 Ответ

3 голосов
/ 01 декабря 2011

CancellationToken и CancellationTokenSource были добавлены в .net в 4.0 и с тех пор составляют основу для общего шаблона отмены.Как правило, асинхронные методы имеют перегрузку, которая принимает CancellationToken.

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

CancellationToken - это интерфейс, используемый асинхронной задачей, инициатор задачи использует CancellationTokenSource для выдачи этого токена.и может затем отменить его в будущем.

Одна из приятных сторон этого подхода, помимо того, что он становится стандартным способом подхода к отмене, состоит в том, что он является составным.Если задача состоит из нескольких других отменяемых асинхронных операций, один и тот же токен отмены может быть передан им, и отмена должна автоматически сработать.

...