在协程被取消时,如果它被标记为不可取消,将会引发CancellationException异常。这可以通过使用withContext函数和NonCancellable上下文来解决。
以下是一个包含代码示例的解决方法:
import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            withContext(NonCancellable) {
                repeat(1000) { i ->
                    println("Job: I'm sleeping $i ...")
                    delay(500L)
                }
            }
        } catch (e: CancellationException) {
            println("Job: I'm cancelled, but not throwing CancellationException")
        }
    }
    delay(1300L) // 等待一段时间
    println("Main: I'm tired of waiting!")
    job.cancelAndJoin() // 取消协程并等待它结束
    println("Main: Now I can quit.")
}
在上面的示例中,withContext(NonCancellable)函数将协程的执行上下文设置为不可取消的上下文。因此,即使协程被取消,它也不会引发CancellationException异常。相反,它将捕获并处理CancellationException异常,并在catch块中打印消息。
运行上述代码,你会看到输出类似于以下内容:
Job: I'm sleeping 0 ...
Job: I'm sleeping 1 ...
Job: I'm sleeping 2 ...
Main: I'm tired of waiting!
Job: I'm cancelled, but not throwing CancellationException
Main: Now I can quit.
如你所见,尽管协程被取消,但它不会抛出CancellationException异常。