我遵循Coroutine(https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html)上的参考文档,并同时在Android Studio(一个好孩子)上测试了该示例。
但是我对cancelAndJoin()方法非常困惑。
如果在示例代码中将“ cancelAndJoin”替换为“ join”,则日志中没有任何区别。
这是代码:
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (i < 5) { // computation loop, just wastes CPU
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
,在2种情况下(使用join或cancelAndJoin),日志为:
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
job: I'm sleeping 3 ...
job: I'm sleeping 4 ...
main: Now I can quit.
有人能解释这两种方法有什么区别吗?
这还不清楚,因为取消是“停止工作”,联接是“等待完成”,但是两者在一起???我们“停止”并“等待” ???
非常感谢:)
答案 0 :(得分:2)
好吧,我刚刚意识到我的问题很愚蠢!
cancelAndJoin()等于先执行cancel(),然后再进行join()。
代码表明,如果不检查作业是否处于活动状态,则无法取消该作业。为此,我们必须使用“ isActive”。
像这样:
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (isActive) { // cancellable computation loop
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
答案 1 :(得分:0)
不清楚,因为取消是“停止工作”,加入是 “等待完成”,但两者在一起???我们“停止”并 “等待”?
仅仅因为我们写了job.cancel()
并不意味着该工作将立即取消。
当我们写job.cancel()
时,job
进入瞬态取消状态。该job
尚未进入最终的完成状态,只有在job
进入完成状态后,它才能被视为完全取消。
有关更多详细信息,请查看this