Arjan van Wieringen
03/26/2023, 6:59 AMSam
03/26/2023, 7:25 AMArjan van Wieringen
03/26/2023, 7:34 AMSam
03/26/2023, 8:02 AMcoroutineScope
function is for concurrent decomposition (also sometimes called parallel decomposition), and lets you break down a task into multiple concurrent subtasks. Because it encapsulates all of the coroutines that you launch inside it, and waits for them to complete or fail, the caller doesn't need to know anything about what's going on inside. It's like a coroutine "black box". From the point of view of the caller, a function that uses coroutineScope
to decompose its execution into concurrent subtasks should be indistinguishable from any other suspend
function.
• The runBlocking
is for bridging non-coroutine code with coroutine code. It should be used rarely and with caution. Generally it should only be used at application entrypoints.
The crucial difference really comes down to composability. With coroutineScope
, you split a coroutine into multiple coroutines, which means that each of those child coroutines can be further decomposed if you want. Whereas with runBlocking
you transform a thread into one or more coroutines, which is a fundamental change of paradigm and is not composable.Sam
03/26/2023, 8:04 AMrunBlocking
emphasises the fact that it blocks the thread, which is important because it highlights the fact that it should not be called from a coroutine and is thus not composable. The blocking is the important attribute. Whereas with coroutineScope
, the suspending is less significant; the interesting thing is the decomposition and the encapsulated scope. That's just my take, though.Sam
03/26/2023, 8:05 AMrunBlocking
would probably not be included at all if the coroutines API could be redesigned with the benefit of hindsight.Joffrey
03/26/2023, 8:09 AMcoroutineScope
to runSuspending
wouldn't make much sense. When calling coroutineScope
we are already in a suspending context, so there is no point in a runSuspending
. The point here is to create a coroutine scope locally in order to launch multiple concurrent child coroutines and wait for their result. The name puts the emphasis on that.Sam
03/26/2023, 8:11 AMrunBlocking
must create its own (by default) whereas coroutineScope
simply inherits. The dispatcher used by runBlocking
is a source of much woe 😬Joffrey
03/26/2023, 8:14 AMcoroutineScope
inherits the context from the current coroutine (because there is a current coroutine), while runBlocking
creates a new context from scratchSam
03/26/2023, 8:21 AMJoffrey
03/26/2023, 8:24 AMrunBlocking
being absent from coroutines if they were redesigned. Surely there would have been a way to bridge blocking and coroutine worldsSam
03/26/2023, 8:26 AMsuspend fun main
if coroutines are needed. But of course reality is never that easy.