Is there a way to add a task to do when a coroutin...
# coroutines
c
Is there a way to add a task to do when a coroutine scope is cancelled? e.g.
Copy code
scope.onCancellation {
    disposeSomeStuff()
}
👀 1
s
Copy code
scope.launch {
    try {
        awaitCancellation()
    } finally {
        disposeSomeStuff()
    }
}
(But it won’t work if the scope was already cancelled)
c
Thanks, do you think it's good practice?
s
It’s what I would do 😄
j
You can also grab the
Job
and add a completion listener https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/invoke-on-completion.html it will be invoked synchronously if the job is already canceled
this callback is invoked on more cases so if you only care about cancelation you need to check for that
c
Oh, that's great, thanks
b
Note invokeOnCompletion is slightly different. It will be invoked only when the job's children are completed. If any of them are not cooperative for cancellation it may be invoked with a delay (or not invoked at all). If you need a callback as soon as scope gets cancelled use the first answer (I would add atomic/undispatched launch to it to handle an already cancelled scope).
we have this ext fun (essentially the first answer):
Copy code
fun CoroutineScope.invokeOnCancellation(block: () -> Unit) {
    launch(start = CoroutineStart.ATOMIC) {
        try {
            awaitCancellation()
        } finally {
            block()
        }
    }
}