I'm following the "Kotlin coroutine deep dive" book to understand coroutine a bit further. I came across the below statement in the book which I can't understand clearly and would be helpful if someone explain me with a simple example.
CancellationException can be caught using a try-catch, but it is recommended to rethrow it.
And he gave an example,
import kotlinx.coroutines.*
suspend fun main(): Unit = coroutineScope {
val job = Job()
launch(job) {
try {
repeat(1_000) { i ->
delay(200)
println("Printing $i")
}
} catch (e: CancellationException) {
println(e)
throw e
}
}
delay(1100)
job.cancelAndJoin()
println("Cancelled successfully")
delay(1000)
}
As you can see, it catches catch (e: CancellationException)
and rethrow it, now I wonder what happens if I don't rethrow it. I commented out the throw e
but the code executes as usual.
As I can see from kotlin doc, CancellationException is used for structured concurrency which means the CancellationException won't cancel the parent instead it signals the parents to cancel all the other children of the parent (Am I right here ?)
I believe that my understanding is wrong and the below code proves that,
import kotlinx.coroutines.*
fun main() = runBlocking {
val parentJob = launch {
launch {
println("Starting child 1")
delay(1000)
throw CancellationException("Close other child under this parent")
}
launch {
println("Starting child 2")
delay(5000)
println("This should not be printed, but getting printed. Don't know why?")
}
delay(2000)
println("Parent coroutine completed")
}
parentJob.join()
}
As you see, I have created a parentJob
and two child jobs inside then I terminate child 1
by throwing CancellationException
and expecting that parent has to cancel child 2
but not.