tjohnn
03/26/2019, 11:00 AMfun main() = runBlocking {
//sampleStart
launch {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
}
delay(1300L) // just quit after delay
//sampleEnd
}
Prints 3 lines and exits because it uses a daemon thread
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
But main waits for coroutineScope
to finish execution
fun main() = runBlocking { // this: CoroutineScope
launch {
delay(200L)
println("Task from runBlocking")
}
coroutineScope { // Creates a new coroutine scope
launch {
delay(900L)
println("Task from nested launch")
}
delay(100L)
println("Task from coroutine scope") // This line will be printed before nested launch
}
println("Coroutine scope is over") // This line is not printed until nested launch completes
}
And prints this
Task from coroutine scope
Task from runBlocking
Task from nested launch
Coroutine scope is over
Is there a magic done by coroutineScope
that makes it block the main from finishing? Any help is appreciated.marstran
03/26/2019, 11:04 AMI'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
I'm sleeping 3 ...
I'm sleeping 4 ...
marstran
03/26/2019, 11:05 AMcoroutineScope
will wait for all child-coroutines to complete before the scope completes. The runBlocking
function also creates a coroutinescope that will behave that way.r4zzz4k
03/26/2019, 11:36 AMcoroutineScope { ... }
is akin to runBlocking { ... }
, with the difference that it suspends and not blocks. There are of course subtle differences under the hood as runBlocking
sets up the bridge between blocking and non-blocking worlds in the absence of external event loop (and that's the only legitimate use case for this function), but you can skip that for the time being.tjohnn
03/26/2019, 11:47 AMtjohnn
03/26/2019, 11:51 AMrunBlocking
waits for coroutineScope
to finish executing its nested coroutines but doesn't wait for coroutines like launch
to finish execution, is that right?marstran
03/26/2019, 11:52 AMlaunch
too.marstran
03/26/2019, 11:52 AMlaunch
on another scope.tjohnn
03/26/2019, 11:55 AMfun main() = runBlocking {
//sampleStart
coroutineScope{
launch {
repeat(20) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
}
}
println("Finished with launch blocking")
delay(1300L) // just quit after delay
println("Exiting main")
//sampleEnd
}
It printed the whole 20 "I am sleeping" before exiting, But without wrapping the repeat
in coroutineScope
, it stoped at the third looptjohnn
03/26/2019, 12:06 PMmarstran
03/26/2019, 12:11 PMcoroutineScope
. I think you just need to wait longer.tjohnn
03/26/2019, 12:18 PMcoroutineScope
, "Exiting main" will be the last line to be printed. In your example without coroutineScope
, it "Exiting main" is printed on the 6th linetjohnn
03/26/2019, 12:22 PMtjohnn
03/26/2019, 12:24 PMcoroutineScope
doesn't allow runBlocking
to execute next line until it finishes but launch
does allow it ?marstran
03/26/2019, 12:40 PMcoroutineScope
will only wait for child-coroutines when the scope exists (at the }
). It does not have anything to do with launch
running asynchronously.marstran
03/26/2019, 12:41 PMcoroutineScope
around launch
, it was just waiting for launch
to finish.tjohnn
03/26/2019, 12:50 PM