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 scopeJoffrey
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.andwithContextfacilitates 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 provideslaunchas implicit receiver on itsCoroutineScopeargument 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