При каких обстоятельствах асинхронный метод должен поддерживать отмену

В настоящее время я создаю асинхронную версию существующего API, и я изо всех сил пытаюсь найти какие-либо рекомендации о том, когда рекомендуется поддерживать отмену. Некоторые асинхронные методы в BCL не имеют перегрузки, которая принимает CancellationToken, и я нашел это Статья MSDN, в которой говорится

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

Итак, при каких условиях стоит поддерживать отмену через CancellationToken?

Я склоняюсь к следующим условиям:

  • Любой вызываемый ожидаемый метод также поддерживает отмену
  • Выполнение любого ожидаемого метода может занять больше времени, чем n мс.
  • Реализация метода имеет одну или несколько логических точек выхода (например, отсутствие побочных эффектов от досрочного выхода)

Это разумные условия? есть другие?


person Trevor Pilley    schedule 22.10.2014    source источник


Ответы (1)


Это всего лишь мое мнение, но я бы сказал, что если async методы, которые вы вызываете все, поддерживают отмену, то и ваши должны. Аналогичным образом, если вы создаете awaitable API для естественно асинхронной операции, сделайте все возможное, чтобы поддерживать отмену (например, через CancellationToken.Register).

Я бы также сказал, что любой (синхронный) метод с привязкой к ЦП, который может занять «долгое время», должен периодически отслеживать токен отмены (CancellationToken.ThrowIfCancellationRequested). «Долгое время» относительно, но в качестве грубого ориентира я бы сказал что-то более полсекунды (на старом оборудовании, а не на наших 8-ядерных машинах для разработчиков;).

В любом другом сценарии вы говорите о гораздо менее полезной форме отмены — в частности, отмена может занять произвольное время, чтобы вступить в силу. Например, если некоторые методы async поддерживают это, а другие нет. Я не уверен, насколько полезным в этом случае будет параметр маркера отмены; вы можете добавить его, но не забудьте задокументировать его ограничения.

person Stephen Cleary    schedule 23.10.2014
comment
Итак, если мой асинхронный метод вызывает 3 других асинхронных метода, и только 2 из них поддерживают отмену, вы не думаете, что мой метод тоже должен его поддерживать? - person Trevor Pilley; 24.10.2014
comment
Я говорю, что если все 3 подходят, то и ваш точно должен. Если только 2, то ответ не так ясен; вы можете вставить это, но хорошо задокументируйте это. Я не говорю, что вы не должны, просто имейте в виду, что существует произвольное количество времени, в течение которого ваша отмена не будет иметь никакого эффекта. - person Stephen Cleary; 24.10.2014