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.