Ser*_*gey 5 android coroutine kotlin kotlin-coroutines kotlin-flow
我有一个CoroutineScope和log()函数的实例,如下所示:
private val scope = CoroutineScope(Dispatchers.IO)
fun log(message: String) = scope.launch { // launching a coroutine
println("$message")
TimeUnit.MILLISECONDS.sleep(100) // some blocking operation
}
Run Code Online (Sandbox Code Playgroud)
我使用这个测试代码来启动协程:
repeat(5) { item ->
log("Log $item")
}
Run Code Online (Sandbox Code Playgroud)
该log()函数可以从任何位置、任何位置调用Thread,但不能从协程调用。
经过几次测试后,我可以看到不连续的结果,如下所示:
Log 0
Log 2
Log 4
Log 1
Log 3
Run Code Online (Sandbox Code Playgroud)
打印日志的顺序可以不同。如果我理解正确的话,协程的执行并不能保证是顺序的。这意味着协程 foritem 2可以在协程 for 之前启动item 0。
我希望协程针对每个项目按顺序启动,并且“某些阻塞操作”将按顺序执行,以始终实现下一个日志:
Log 0
Log 1
Log 2
Log 3
Log 4
Run Code Online (Sandbox Code Playgroud)
有没有办法让协同程序按顺序启动?或者也许还有其他方法可以实现我想要的?
预先感谢您的任何帮助!
一种可能的策略是使用 Channel 按顺序加入已启动的作业。join您需要延迟启动作业,以便它们在被调用之前不会启动。trySend当通道容量无限时,总是会成功。您需要使用它trySend,以便可以从协程外部调用它。
private val lazyJobChannel = Channel<Job>(capacity = Channel.UNLIMITED).apply {
scope.launch {
consumeEach { it.join() }
}
}
fun log(message: String) {
lazyJobChannel.trySend(
scope.launch(start = CoroutineStart.LAZY) {
println("$message")
TimeUnit.MILLISECONDS.sleep(100) // some blocking operation
}
)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10716 次 |
| 最近记录: |