import kotlinx.coroutines.*
fun main() = runBlocking {
println("Main program starts: ${Thread.currentThread().name}")
withContext(Dispatchers.IO.limitedParallelism(1)) {
println("Switched to limited parallelism context: ${Thread.currentThread().name}")
repeat(2) { i ->
launch {
println("Coroutine $i starts on thread ${Thread.currentThread().name}")
delay(1000L)
}
}
}
println("Main program ends: ${Thread.currentThread().name}")
}
上述 Kotlin 代码打印以下结果
Main program starts: main
Switched to limited parallelism context: DefaultDispatcher-worker-1
Coroutine 0 starts on thread DefaultDispatcher-worker-1
Coroutine 1 starts on thread DefaultDispatcher-worker-1
Main program ends: main
但是如果我编写一个自定义函数,withContext(Dispatchers.IO.limitedParallelism(1))
那么里面的代码的行为withContext
就会改变。
import kotlinx.coroutines.*
fun main() = runBlocking {
println("Main program starts: ${Thread.currentThread().name}")
atomically {
println("Switched to limited parallelism context: ${Thread.currentThread().name}")
repeat(2) { i ->
launch {
println("Coroutine $i starts on thread ${Thread.currentThread().name}")
delay(1000L)
}
}
}
println("Main program ends: ${Thread.currentThread().name}")
}
internal suspend inline fun <R> atomically(crossinline f: () -> R): R =
withContext(Dispatchers.IO.limitedParallelism(1)) { f() }
上述 Kotlin 代码打印以下结果
Main program starts: main
Switched to limited parallelism context: DefaultDispatcher-worker-1
Coroutine 0 starts on thread main
Coroutine 1 starts on thread main
Main program ends: main
如您所见, 中的两个子协程withContext
并未在 上启动,DefaultDispatcher
而是在 上运行main
。我想了解为什么会发生这种行为变化。
您的问题来自于
f
您提取的函数中的函数参数没有接收CoroutineScope
器。因此,嵌套协程启动不会在子作用域上进行,withContext
而是在上一级协程作用域上进行。要修复此问题,只需添加一个
CoroutineScope
接收器f
: