методами download(onResult: (Result) -> Unit) и cancelDownload(), преврарить его в суспенд функцию довольно просто - через suspendCancellableCoroutine передаём continuation в колбек, а при отмене в invokeOnCancellation вызываем cancelDownload().
А как быть с блокируещей версией download()? Просто withContext(IO) не подходит потому что CancellationException не вылетает до окончания вызова блокирующего метода. Что-то похожее получилось сделать через coroutineScope { launch(IO) { download() }.join() }, потому что join() кидает CancellationException сразу как происходит отмена, и можно в catch вызвать cancelDownload(). Нет ли какой-нибудь апишки типа suspendCancellableCoroutine для блокирующих методов?
Продолжать выполение корутины, пока в фоне что-то крутится - это прямое нарушение structured concurrency. Если отмена не поддерживается, остаётся только ждать окончания выполнения. Но вообще есть одно средство в блокирующем коде: InterrupedException. Если этот ваш метод умеет прерываться через прерывание потока, оберните его в runInterruptible { }.
Да, кажется runInterruptible это то что нужно
Обсуждают сегодня