После перечитывания документации об отмене кажется, что сопрограммы должны сотрудничать, чтобы быть отменяемыми:
Отмена сопрограммы является кооперативной.Код сопрограммы должен взаимодействовать, чтобы его можно было отменить.
https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html#cancellation-is-cooperative
Я также обнаружил, что потоки по замыслу не прерываются:
Отмена сопрограммы не прерывает поток.Это сделано специально, потому что, к сожалению, многие библиотеки Java некорректно работают в прерванных потоках.
https://discuss.kotlinlang.org/t/calling-blocking-code-in-coroutines/2368/6
Это объясняет, почему код ожидает ожиданиядо конца.
Это также означает, что невозможно использовать withTimeout для сопрограммы, которая блокирует поток для добавления тайм-аута.
При использовании неблокирующей библиотеки, которая возвращает фьючерсы, можно использовать withTimeout, как описано здесь:
Чтобы правильно интегрироваться с отменой, CompletableFuture.await () использует то же соглашение, что и все будущие комбинаторы - он отменяет базовое будущее, если отменен сам вызов await.
https://medium.com/@elizarov/futures-cancellation-and-coroutines-b5ce9c3ede3a
Дополнительное примечание к примеру из документации: добавив операторы журнала в пример задержки / тайм-аута, я обнаружил, что проходит всего 1300 миллисекунд, поэтому задержка отлично работает с withTimeout.
08: 02: 24.736 [main @ coroutine # 1] ИНФОРМАЦИЯ btccCoroutineControllerTest - я сплю 0 ...
08: 02: 25.242 [main @ coroutine # 1] ИНФОРМАЦИЯ btccCoroutineControllerTest - я сплю 1 ...
08: 02: 25.742 [main @ coroutine # 1] ИНФОРМАЦИЯ btccCoroutineControllerTest - Я сплю 2 ...
08: 02: 26.041 [main @ coroutine # 1] INFO btccCoroutineControllerTest - отменено