协程搬运工-取消与超时

简介: 协程搬运工-取消与超时

Job的取消


开发中可能经常有这样一种情况,我们在页面协程中执行一个耗时2s的任务获取数据,获取数据成功展示ui。但是有可能一种情况在协程执行到1s的时候我们的页面被用户返回了,协程中请求的数据不再被需要,此时就需要我们取消协程。

下面代码中的job就是可以被取消的


  1. 代码
fun main() = runBlocking {
    val job: Job = launch {
        repeat(20) {//A
            log(A)
            delay(500)//B
            log(B)
        }
    }
    delay(1700)//C
    job.cancel()//D
}
复制代码


  1. 日志
日志:  A
日志:  B
日志:  A
日志:  B
日志:  A
日志:  B
日志:  A
复制代码
  1. 结论

launch协程体调用cancel后可以取消协程


协程的取消是协作的


  1. 所谓的协作在这里指的就是,如果协程内部在执行耗时任务,那么即使我们取消了协程,也需要计算完成才能真正取消
  2. 如果内部使用挂起函数则可以马上响应取消,如下代码:
fun main() = runBlocking {
    val job = launch(Dispatchers.Default) {
        work()
    }
    delay(1300L) // 等待一段时间
    log(B)
    job.cancelAndJoin() // 取消一个作业并且等待它结束
    log(C)
}
suspend fun work() {
    delay(10)
}
复制代码

上面代码中launch方法内部运行了一个work挂起函数,所以当我们cancelAndJoin的时候,协程立马就被取消了。 3. 如果正在进行密集的计算导致无法取消协程,那么其实有其它方法可以实现。比如我们可以在计算中定期判断Job.isActive判断协程是否活跃来决定是否结束计算。cancel后isActive==false


超时


withTimeOut或withTimeOutOrNull可以响应超时

下面分别介绍一下两个方法


withTimeOut

withTimeOut超时的时候会崩溃

  1. 代码
fun main() = runBlocking {
    val result = withTimeout(3*1000){//运行超过3s就超时
        repeat(20){//正常情况repeat需要20s
            log(A)
            delay(1000)
        }
        "重复结束"
    }
    log(result)
    delay(100)
}
复制代码
  1. 日志
日志:  A
日志:  A
日志:  A
Exception in thread "main" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 3000 ms
复制代码
  1. 结论

withTimeOut可以响应超时,超时的时候会报崩溃日志


withTimeOutOrNull

使用withTimeOutOrNull不会崩溃,超时会返回null 1.代码

将上一个例子做一个小改动即可

fun main() = runBlocking {
    val result = withTimeoutOrNull(3*1000){
        repeat(20){
            log(A)
            delay(1000)
        }
        "重复结束"
    }
    log(result?:"超时了没结果®")
    delay(100)
}
复制代码
  1. 日志
日志:  A
日志:  A
日志:  A
日志:  超时了没结果
复制代码
  1. 结论

withTimeOutOrNull超时不会报错,而且会返回null



相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
Java 调度
协程搬运工-上下文和调度器
协程搬运工-上下文和调度器
248 0
协程搬运工-组合挂起函数
协程搬运工-组合挂起函数
219 0
|
4月前
|
Go 调度 Python
Golang协程和Python协程用法上的那些“不一样”
本文对比了 Python 和 Go 语言中协程的区别,重点分析了调度机制和执行方式的不同。Go 的协程(goroutine)由运行时自动调度,启动后立即执行;而 Python 协程需通过 await 显式调度,依赖事件循环。文中通过代码示例展示了两种协程的实际运行效果。
209 7
|
3月前
|
数据采集 网络协议 API
协程+连接池:高并发Python爬虫的底层优化逻辑
协程+连接池:高并发Python爬虫的底层优化逻辑
|
5月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
Go Python
使用python实现一个用户态协程
【6月更文挑战第28天】本文探讨了如何在Python中实现类似Golang中协程(goroutines)和通道(channels)的概念。文章最后提到了`wait_for`函数在处理超时和取消操作中的作
238 1
使用python实现一个用户态协程
|
数据库 开发者 Python
实战指南:用Python协程与异步函数优化高性能Web应用
【7月更文挑战第15天】Python的协程与异步函数优化Web性能,通过非阻塞I/O提升并发处理能力。使用aiohttp库构建异步服务器,示例代码展示如何处理GET请求。异步处理减少资源消耗,提高响应速度和吞吐量,适用于高并发场景。掌握这项技术对提升Web应用性能至关重要。
287 10
|
调度 Python
python3 协程实战(python3经典编程案例)
该文章通过多个实战案例介绍了如何在Python3中使用协程来提高I/O密集型应用的性能,利用asyncio库以及async/await语法来编写高效的异步代码。
323 0
|
数据处理 Python
深入探索:Python中的并发编程新纪元——协程与异步函数解析
【7月更文挑战第15天】Python 3.5+引入的协程和异步函数革新了并发编程。协程,轻量级线程,由程序控制切换,降低开销。异步函数是协程的高级形式,允许等待异步操作。通过`asyncio`库,如示例所示,能并发执行任务,提高I/O密集型任务效率,实现并发而非并行,优化CPU利用率。理解和掌握这些工具对于构建高效网络应用至关重要。
217 6