Canceling a coroutine

If you are a Java developer, you may know that stopping a thread is quite complicated.

For example, the Thread.stop() method is deprecated. There's Thread.interrupt(), but not all threads are checking this flag, not to mention setting your own volatile flag, which is often suggested but is very cumbersome.

If you're using a thread pool, you'll get Future, which has the cancel(boolean mayInterruptIfRunning) method. In Kotlin, the launch() function returns a job.

This job can be canceled. The same rules as the previous example apply, though. If your coroutine never calls another suspend method or yields, it will disregard cancel().

To demonstrate that, we'll create one nice coroutine that yields once in a while:

val cancellable = launch {
try {
for (i in 1..1000) {
println("Cancellable: $i")
computeNthFibonacci(i)
yield()
}
}
catch (e: CancellationException) {
e.printStackTrace()
}
}

And another one that doesn't yield:

val notCancellable = launch {
for (i in 1..1000) {
println("Not cancellable $i")
computeNthFibonacci(i)
}
}

We'll try to cancel both:

println("Canceling cancellable")
cancellable.cancel()
println("Canceling not cancellable")
notCancellable.cancel()

And wait for the results:

runBlocking {
cancellable.join()
notCancellable.join()
}

A few interesting points:

  1. Canceling the nice coroutine doesn't happen immediately. It may still print a line or two before getting canceled.
  2. We can catch CancellationException, but our coroutine will be marked as canceled anyway. 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.251.206