Kotlin协程-取消与超时

1.Job:取消协程 【类似于线程的cancle、 join】

suspend fun main(args: Array<String>) {

    var job = GlobalScope.launch {
        repeat(1000, {
            println(it)
            delay(500)
        })
    }
    delay(1300)
    println("main start ")

    job.cancel()  // 取消 
    job.join()  //等待job执行完以后

 // job.cancelAndJoin()  将上面两个合二为一

    println("main end ")
}

result:
0
1
2
main start 
main end 

 一般都在finally 中释放资源

suspend fun main(args: Array<String>) {

    var job = GlobalScope.launch {
        try {
            repeat(1000) { i ->
                println("job: I'm sleeping $i ...")
                delay(500L)
            }
        } finally {
           println("释放资源")
        }
    }
    delay(1300)
    println("main start ")
    job.cancelAndJoin()
    println("main end ")
}
result:
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main start 
释放资源
main end 

这里存在一个问题,在finally中如果调用挂起函数(suspend修饰的函数)会抛出异常

suspend fun main(args: Array<String>) {

    var job = GlobalScope.launch {
        try {
            repeat(1000) { i ->
                println("job: I'm sleeping $i ...")
                delay(500L)
            }
        } finally {
            try {
                delay(1000)  //挂起函数
            } catch (e: Exception) {
                println(e)
            }
        }
    }
    delay(1300)
    println("main start ")
    job.cancelAndJoin()
    println("main end ")
}

result:
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main start 
kotlinx.coroutines.JobCancellationException: Job was cancelled; job=StandaloneCoroutine{Cancelling}@20d8d1ae
main end 

解决方案:withContext

suspend fun main(args: Array<String>) {
    var job = GlobalScope.launch {
        try {
            repeat(1000) { i ->
                println("job: I'm sleeping $i ...")
                delay(500L)
            }
        } finally {
            withContext(NonCancellable) {
                println("job: I'm running finally")
                delay(1000L)
                println("job: And I've just delayed for 1 sec because I'm non-cancellable")
            }
        }
    }
    delay(1300)
    println("main start ")
    job.cancelAndJoin()
    println("main end ")
}
result:
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main start 
job: I'm running finally
job: And I've just delayed for 1 sec because I'm non-cancellable
main end 

2.超时:withTimeout  withTimeoutOrNull



//withTimeout
suspend fun main(args: Array<String>) {
    withTimeout(1500,{
        repeat(1000) { i ->
            println("job: I'm sleeping $i ...")
            delay(500L)
        }
    })
    println("main end ")
}

result:
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
Exception in thread "main" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1500 ms
	at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:124)
	at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:90)
	at kotlinx.coroutines.EventLoopImplBase$DelayedRunnableTask.run(EventLoop.kt:307)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116)
	at kotlinx.coroutines.DefaultExecutor.run(DefaultExecutor.kt:68)
	at java.lang.Thread.run(Thread.java:745)

//withTimeoutOrNull
suspend fun main(args: Array<String>) {
    var c = withTimeoutOrNull(1500,{
        repeat(1000) { i ->
            println("job: I'm sleeping $i ...")
            delay(500L)
        }
    })
    println(c) //返回null
    println("main end ")
}
result:
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
null
main end

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值