Kotlin 如何正确处理协同程序中的取消';什么是计算代码?
以下是我对协同程序取消的理解: 如果父协同程序被取消,子进程也将停止。如果 子协同程序抛出异常、同级和父协同程序 我会注意到并停止 除SupervisorJob外,即使其中一个 子协同程序已停止 所以,我写了一段代码来练习我的理解 代码片段1Kotlin 如何正确处理协同程序中的取消';什么是计算代码?,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,以下是我对协同程序取消的理解: 如果父协同程序被取消,子进程也将停止。如果 子协同程序抛出异常、同级和父协同程序 我会注意到并停止 除SupervisorJob外,即使其中一个 子协同程序已停止 所以,我写了一段代码来练习我的理解 代码片段1 fun main() { val parentScope = CoroutineScope(SupervisorJob()) parentScope.launch { val childJob = launch {
fun main() {
val parentScope = CoroutineScope(SupervisorJob())
parentScope.launch {
val childJob = launch {
try {
println("#1")
Thread.sleep(1_000)
println("#2")
} catch (e: Exception) {
println("#3")
}
}
println("#4")
childJob.cancel()
}
Thread.sleep(2_000)
}
以下是我的两个期望:
期望1:
#1 is called first because there's no blocking code between child and parent job.
#4 is called because `Thread.sleep` is blocking.
#3 is called because the childJob is cancelled, even though the coroutine is not finished.
期望2:
#4 is called first because the parent coroutine start first.
#1 is called because even though the childJob is cancelled, there's time for #1 to be executed.
但是,代码段1的实际输出是:
#4
#1
#2
我又读了一遍,发现对于计算代码,我们要么使用屈服
,要么检查协同程序状态(活动
,取消
,已完成
)。然后我进行以下调整:
代码片段2
fun main() {
val parentScope = CoroutineScope(SupervisorJob())
parentScope.launch {
val childJob = launch {
try {
println("#1")
Thread.sleep(1_000)
if (isActive) {
println("#2")
}
} catch (e: Exception) {
println("#3")
}
}
println("#4")
childJob.cancel()
}
Thread.sleep(2_000)
}
这一次的输出是:
#4
#1
以下是我的问题:
childJob
后#2如何仍然执行childJob
也从不执行#3yield
还是每次执行协同程序代码时都要检查协同程序状态?因为在我看来,代码将更难阅读GlobalScope.runBlocking
,因为在实际项目中,我们无论如何都不使用GlobalScope
。我想创建一个尽可能接近实际项目的示例,使用具有某种生命周期的父子范围
在代码片段1中,在执行childJob之后,如何仍然执行#2
取消了
只挂起函数。将线程睡眠(1_000)
替换为挂起,它将被取消
在代码片段1中,为什么即使childJob是
打电话
那是因为联欢会没有取消。请参见第一个问题的答案
在代码片段2中,我们真的需要使用yield还是checking
每次我们想要执行协同程序代码时,协同程序状态是什么?
因为在我看来,代码将更难阅读
不,你不应该。每个挂起的函数都检查是否取消了协同路由
我的代码片段或我的理解是否有问题
协同程序
在使用协同程序时,了解挂起函数是非常重要的。文档部分对此进行了很好的解释。而且可能是有用的