Applying Kotlin Structured concurrency: Part IV — Coroutines Cancellation
source link: https://proandroiddev.com/applying-kotlin-structured-concurrency-part-iv-coroutines-cancellation-ba51470acefe
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Structured concurrency helps to cancel coroutines not only individually one by one but also centralised using root coroutine — cancelation of parent coroutine canceling child coroutines too.
CancellationException
Coroutine cancellation is throwing a CancellationException
. A cancellation is just a specific type of exception that is treated differently from a failure.
There is a difference in CancellationException
propagation in comparison with other exceptions — this exception cancels itself and child coroutines while other exceptions cancel itself, child, siblings and parent coroutines.
Avoid scope job cancellation
You can cancel parent scope with all child coroutines.
But after cancellation you can’t start coroutine again in that cancelled scope. If you cancelling scope — you cancel all child coroutines.
When we cancel job we put it into the completed state. Coroutines launched in a scope of the completed job will not be executed.
Cancel all coroutines in scope
When you want to cancel all coroutines of a specific scope, you can use cancelChildren()
function. Also, it’s a good practice to provide the possibility to cancel individual jobs.
Cancel job
You can cancel specific coroutine without affecting siblings cancelling specific job.
Cooperative cancellation
If you try to cancel coroutine during long operation you can not always get expected behaviour:
Coroutines cancellation is cooperative — so you need to check if coroutine was cancelled using job.isActive
or ensureActive()
. The difference between isActive
and ensureActive
is that the latter immediately throws a CancellationException
if the job is no longer active.
But you can fix it even simpler: you can change Thread.sleep()
to delay()
then it starts to work as expected. Why? All suspend functions from kotlinx.coroutines
are cancellable: withContext
, delay
etc.
There is one more useful function — yeild()
. In addition to checking the cancellation status of the job, the underlying thread is released and is made available for other coroutines.
Don’t catch cancellation exception
You should remember — coroutines cancellation works by trowing CancellationException
so you should have separate catch
for it.
You should strive to make your suspending functions cancellable. A suspending function can be made of several suspending functions. All of them should be cancellable.
try {
someWork()
} catch (e: Throwable) {
if (e is CancellationException) {
throw e
}
...
}
Thank you for reading!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK