franztesca
02/21/2023, 2:08 PMdownloadSomething(onCompleted: () -> Unit): DownloadTasksuspendCancellableCoroutineDownloadTasksuspendCancellableCoroutineCancellationExceptionDownloadTasksuspendCancellableCoroutineAwaiting@OptIn(ExperimentalCoroutinesApi::class)
private suspend inline fun <T> suspendCancellableCoroutineAwaiting(
    crossinline block: (CancellableContinuation<T>) -> Unit,
): T {
    val job = Job()
    return try {
        suspendCancellableCoroutine { cont ->
            val wrapperContinuation = object : CancellableContinuation<T> by cont {
                override fun resumeWith(result: Result<T>) {
                    job.complete()
                    cont.resumeWith(result)
                }
                override fun resume(value: T, onCancellation: ((cause: Throwable) -> Unit)?) {
                    job.complete()
                    cont.resume(value, onCancellation)
                }
            }
            block(wrapperContinuation)
        }
    } finally {
        withContext(NonCancellable) {
            job.join()
        }
    }
}Sam
02/21/2023, 2:39 PMsuspend fun download() = coroutineScope {
    val downloadJob = Job()
    val task = downloadSomething { downloadJob.complete() }
    launch(start = CoroutineStart.ATOMIC) {
        try {
            awaitCancellation()
        } finally {
            task.cancel()
        }
    }
    withContext(NonCancellable) {
        downloadJob.join()
    }
}Sam
02/21/2023, 2:39 PMDownloadTaskcancelfranztesca
02/22/2023, 3:35 PMawaitCancellationSam
02/22/2023, 3:38 PMuli
02/23/2023, 1:26 PMsuspendCoroutinefranztesca
02/23/2023, 11:24 PMuli
02/24/2023, 8:56 AMSam
02/24/2023, 8:59 AMuli
02/24/2023, 9:06 AMuli
02/24/2023, 9:07 AMdownloadSomething