Переносит ли suspend выполнение на Dispatchers.IO?Нет. suspend меняет возможности функции по приостановке; поток определяется контекстом и реализацией вызываемых API. Контекст и диспетчеры.
Зачем пробрасывать CancellationException?Чтобы остановка задачи не превратилась в успешный fallback или бесконечный retry. Отмена является управляющим сигналом иерархии Job. Kotlin: исключения корутин.
Можно ли отложить ошибку async до await в обычном coroutineScope?Результат читается через await, но ошибка ребёнка уже может отменить scope и соседей. Для независимых результатов нужен supervisorScope и явная обработка await. Kotlin: исключения корутин.
Почему supervisorScope не спас от ошибки блока?Изоляция касается ошибок дочерних корутин. Если исключение вышло из тела supervisorScope, он завершается с ошибкой и отменяет детей. Kotlin: исключения корутин.
Что будет при повторном захвате того же Mutex?Без owner-токена попытка может приостановиться, ожидая собственную блокировку. С тем же ненулевым owner API диагностирует повторный захват. Разделяйте функции с захватом и функции, требующие уже удерживаемый lock. Mutex.
Как остановить длинный цикл без delay?Периодически проверять Job через ensureActive; для передачи выполнения другим корутинам можно использовать yield. Один cancel не прерывает произвольные вычисления. ensureActive.