Kotlin协程-取消与超时

it2022-05-05  129

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

 


最新回复(0)