Cancellations and Timeouts
We'll cover the following...
Coroutines can be cancelled, which will stop the code within the coroutine from further execution. Coroutine cancellations aren’t related to the thread terminations that we’re used to in Java. Cancellations are lightweight and have effect across the hierarchy of coroutines that share context.
Both the Job object, which is returned by launch()
, and the Deferred<T>
object, which is returned by async()
, have a cancel()
and a cancelAndJoin()
method. We can use these methods to explicitly cancel a coroutine, but there’s a catch. A coroutine is cancelled only if it is currently in a suspension point. If a coroutine is busy executing code, it won’t receive the cancellation notice and may not bail out. Let’s discuss this further and find ways to deal with this behavior.
Kotlin provides structured concurrency, where coroutines that share a context form a hierarchical relationship. Coroutines that belong to a hierarchy follow some rules and exhibit prescribed behaviors:
-
A coroutine is considered to be a child of another coroutine if it shares the context of the coroutine that creates it.
-
A parent coroutine completes only after all its children complete.
-
Cancelling a parent cancels all its children.
-
A coroutine that has entered a suspension point may receive a
CancellationException
thrown from the suspension point. -
A coroutine that is busy, that’s not in a suspension point, may check an
isActive
property to see if it was cancelled when it was busy. -
If a coroutine has resources to clean up, that needs to happen within the
finally
block within the coroutine. -
An unhandled exception will result in the cancellation of a coroutine.
-
If a child coroutine fails, it will result in the parent coroutine cancelling and thus result in cancellation of the coroutine’s siblings. You can modify this behavior using supervised jobs that make cancellation unidirectional, from parent to children.
That’s a lot of information in one place, but you can refer back to this when working with coroutines. Let’s examine these ideas with some examples.
Cancelling coroutines
If we don’t care for the completion of a task that we started in a coroutine, we may cancel it by calling cancel()
or cancelAndJoin()
on the Job
or the Deferred<T>
instance. ...