取消
我们可以启动协程,也可以在协程尚未结束时,主动取消协程。
例如在Android应用中,一个界面的ViewModel启动了协程,而这个界面要关闭退出了。那么我们需要把协程也取消掉。
launch
函数返回的Job即是协程对象。调用job.cancel()
函数即可取消协程。
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = GlobalScope.launch {
repeat(100) {
i ->
println("休眠次数 $i")
delay(500)
}
}
val t1 = System.currentTimeMillis()
delay(1200)
println("[rustfisher] 等待完毕准备退出 t1:$t1")
job.cancel()
job.join()
println("Bye~ 耗时: ${
System.currentTimeMillis() - t1}毫秒")
}
运行结果
休眠次数 0
休眠次数 1
休眠次数 2
[rustfisher] 等待完毕准备退出 t1:1632750920587
Bye~ 耗时: 1218毫秒
调用job.cancel()
,通过log可以看出在它没有输出了,因为它被取消了。
我们也可以调用Job的cancelAndJoin()
方法来代替上面代码中的cancel()
和join()
。
// Job.kt 部分源码
public suspend fun Job.cancelAndJoin() {
cancel()
return join()
}
检查取消情况
协程在协作的情况下才能被取消。kotlinx.coroutines
中的挂起函数都是可被取消的。
无法取消
如果协程在执行计算任务,并且没检查取消的话,那我们的取消尝试会失败。比如下面的代码
import kotlinx.coroutines.*
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0