harry.singh
02/21/2022, 8:46 PMcoroutineScope
by launching a coroutine inside coroutineScope
and then cancelling it. I was expecting the child coroutine to cancel but seems it continue to run even after being cancelledharry.singh
02/21/2022, 8:46 PMfun main() = runBlocking {
val job = coroutineScope {
launch {
delay(1000)
println("Is the coroutine cancelled? $isActive")
println("From coroutine inside coroutine scope")
}
}
job.cancel()
}
Here's the code that I triedharry.singh
02/21/2022, 8:46 PMIs the coroutine cancelled? true
From coroutine inside coroutine scope
Joffrey
02/21/2022, 8:47 PMcoroutineScope
is a suspending function that suspends until all child coroutines complete. This means the line job.cancel()
cannot be reached here until the child coroutine is actually done. It would work if it were reachedharry.singh
02/21/2022, 8:51 PMharry.singh
02/21/2022, 8:51 PMcoroutineScope
itself is not a coroutine right?Joffrey
02/21/2022, 8:54 PMJoffrey
02/21/2022, 8:59 PMcoroutineScope
usage, here is an example that uses coroutineScope
in a more common way:
https://pl.kotl.in/3vVQzIJq2harry.singh
02/21/2022, 9:08 PMAll of this without the need to provide some external scope to run your child coroutinesNot sure what external scope means here and how
coroutineScope
helps hereJoffrey
02/21/2022, 9:33 PMCoroutineScope
from somewhere. Using coroutineScope
, it gets an instance of CoroutineScope
, which it can use to launch coroutines.Joffrey
02/21/2022, 9:40 PMCoroutineScope
to launch the coroutines in, because we need to have some sort of lifetime for those coroutines so they can be cancelled properly. These functions usually shouldn't be marked suspend
, and by convention they are often declared as extensions on CoroutineScope
. They have this kind of signature:
fun CoroutineScope.doSomethingThatLaunchesCoroutines() { ... }
Functions from the second group can use withContext
or coroutineScope
to scope their coroutines, because they will not return (resume) before the coroutines are done. This means they will automatically cancel their child coroutines if the coroutine in which the function is called is cancelled, so there is no leak, and yet no need to get a scope as argument or receiver.harry.singh
02/21/2022, 10:45 PMwithContext
and coroutineScope
facilitates coroutine launch and make sure that we don't proceed until all the child coroutines from these scopes are finished.
But launch
also provides CoroutineScope
as implicit receiver on its block
argument meaning it also facilitates launching coroutines. And in this case, I think it will launch coroutines and will just return not waiting for child coroutines to complete. Will this also cancel all of the child coroutines if parent launch
is cancelled?Joffrey
02/21/2022, 10:47 PMSoExactly.andwithContext
facilitates coroutine launch and make sure that we don't proceed until all the child coroutines from these scopes are finished.coroutineScope
The coroutine started byalso provideslaunch
as implicit receiver on itsCoroutineScope
argument meaning it also facilitates launching coroutines. And in this case, I think it will launch coroutines and will just return not waiting for child coroutines to complete.block
launch
will wait for its child coroutines to finish before completing. But the call to launch
will indeed return immediately.
Will this also cancel all of the child coroutines if parentYes (at least in general, unless you override the Job in the coroutine context of child coroutines)is cancelled?launch
harry.singh
02/21/2022, 10:47 PMlaunch
execute concurrently?Joffrey
02/21/2022, 10:50 PMlaunch
are run concurrently with each other, and concurrently with the rest of the body of the launch
:
launch { // parent launch
launch { // child launch 1
// concurrent with the code that follows in the parent launch
}
// code here is concurrent with child launch 1
launch { // child launch 2
// concurrent with child launch 1 if not already completed
}
// code here is concurrent with child launch 1 and 2
}
harry.singh
02/21/2022, 10:59 PM