10

Applying Kotlin Structured concurrency: Part IV — Coroutines Cancellation

 1 year ago
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.
neoserver,ios ssh client

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.

1*XZpnMZjycuXlbVH-D7vQ4w.png

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!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK