text
public suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return suspendCoroutineUninterceptedOrReturn { uCont -> val coroutine = ScopeCoroutine(, uCont, true) (coroutine, block) } }
It's asuspend
Function, creates a new coroutine scope and executes a specified code block within that scope, it does not start coroutines. The purpose of its existence is to perform parallel decomposition that conforms to structured concurrency (i.e. split long time-consuming tasks into multiple short time-consuming tasks that are concurrent, and wait for all concurrent tasks to complete before returning).
coroutineScope
andrunBlocking
The difference isrunBlocking
will block the current thread, andcoroutineScope
The coroutine that is located will be suspended until its internal tasks (including child coroutines) are completed, and it will not block the thread that is located.
coroutineScope
is a suspended function. After it is suspended, it will instead execute the previous child coroutine.
fun main() = runBlocking { launch { //launch① delay(1000) //Hang launch① println("test2") } println("test1") coroutineScope { //The first time the runBlocking is suspended until the internal logic is completed launch { //launch② delay(2000) //Hang launch② println("test3") } delay(5000) //delay① //Suspend runBlocking for the second time println("test4") } println("test5") } //test1 //test2 //test3 //test4 //test5
Code Analysis
-
runBlocking
existmain
The thread creates and starts a blocking coroutine; - create
launch①
As a child coroutine, it takes some time to create a coroutine, and the creation of a coroutine is done by a specific thread, not a main thread. Therefore, subsequent code will be executed in parallel during the creation of the coroutine. thereforetest1
Being output. - Execute to
coroutineScope
When function,runBlocking
Pending until the internal logic execution is complete. - Then create
launch②
Coroutine, execute subsequent code during creation:delay①
Continue to hangrunBlocking
5s (the suspend function is called in the suspend function). - wait until
launch①
When the creation is complete, hang it for 1s.launch②
When the creation is finished, hang it for 2 seconds. - at this time
runBlocking、launch①、launch②
All are suspended. - Wait until 1s
launch①
Recover, outputtest2
;After 2 secondslaunch②
Recovered, outputtest3
;After 5srunBlocking
The second hang is restored, the output istest4
。 - at this time
coroutineScope
The logic in the process has been completed and restoredrunBlocking
The first time hangs,test5
Being output.
This is difficult to understand, and the following cases are a little easier:
fun main() = runBlocking { launch { println("test3") } println("test1") coroutineScope { //Hang runBlocking until the internal logic completes println("test2") delay(1000) //Hang runBlocking5s println("test4") } println("test5") //The suspended function coroutineScope must be executed before it is executed} //test1 //test2 //test3 //test4 //test5
And ifcoroutineScope
Change the function todelay
Functions, it will be easier to understand because they are all suspended functions.
fun main() = runBlocking { launch { delay(1000) println("test2") } println("test1") delay(2000) //Hang the runBlocking coroutine 2s println("test3") } //test1 //test2 //test3
coroutineScope
Often used to split a long and time-consuming task into multiple subtasks, so that these subtasks can be executed in parallel.
suspend fun showSomeData() = coroutineScope { val data1 = async { //Subtask 1 delay(2000) 100 } val data2 = async { //Subtask 2 delay(3000) 20 } withContext() { //Merge the results and return delay(3000) val random = Random(10) () + () + (100) } }
coroutineScope
There are the following semantics:
- Perform internal tasks in parallel
data1
、data2
、withContext
- If other tasks (
random
)throw an exception,data1
anddata2
Both tasks will be cancelled - if
showSomeData()
Cancel, internaldata1
、data2
、withContext
Will be cancelled - if
data1
、data2
fail,withContext
Canceled.
The above is the detailed explanation of the coroutineScope function of the kotlin coroutine coroutine. For more information about the coroutineScope function of the kotlin coroutine coroutine, please pay attention to my other related articles!