协程搬运工-取消与超时

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 协程搬运工-取消与超时

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



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
Java 调度
协程搬运工-上下文和调度器
协程搬运工-上下文和调度器
116 0
协程搬运工-组合挂起函数
协程搬运工-组合挂起函数
109 0
|
4月前
|
Go Python
使用python实现一个用户态协程
【6月更文挑战第28天】本文探讨了如何在Python中实现类似Golang中协程(goroutines)和通道(channels)的概念。文章最后提到了`wait_for`函数在处理超时和取消操作中的作
41 1
使用python实现一个用户态协程
|
10天前
|
调度 Python
python3 协程实战(python3经典编程案例)
该文章通过多个实战案例介绍了如何在Python3中使用协程来提高I/O密集型应用的性能,利用asyncio库以及async/await语法来编写高效的异步代码。
11 0
|
3月前
|
数据库 开发者 Python
实战指南:用Python协程与异步函数优化高性能Web应用
【7月更文挑战第15天】Python的协程与异步函数优化Web性能,通过非阻塞I/O提升并发处理能力。使用aiohttp库构建异步服务器,示例代码展示如何处理GET请求。异步处理减少资源消耗,提高响应速度和吞吐量,适用于高并发场景。掌握这项技术对提升Web应用性能至关重要。
75 10
|
3月前
|
数据处理 Python
深入探索:Python中的并发编程新纪元——协程与异步函数解析
【7月更文挑战第15天】Python 3.5+引入的协程和异步函数革新了并发编程。协程,轻量级线程,由程序控制切换,降低开销。异步函数是协程的高级形式,允许等待异步操作。通过`asyncio`库,如示例所示,能并发执行任务,提高I/O密集型任务效率,实现并发而非并行,优化CPU利用率。理解和掌握这些工具对于构建高效网络应用至关重要。
43 6
|
3月前
|
大数据 数据处理 API
性能飞跃:Python协程与异步函数在数据处理中的高效应用
【7月更文挑战第15天】在大数据时代,Python的协程和异步函数解决了同步编程的性能瓶颈问题。同步编程在处理I/O密集型任务时效率低下,而Python的`asyncio`库支持的异步编程利用协程实现并发,通过`async def`和`await`避免了不必要的等待,提升了CPU利用率。例如,从多个API获取数据,异步方式使用`aiohttp`并发请求,显著提高了效率。掌握异步编程对于高效处理大规模数据至关重要。
45 4
|
3月前
|
设计模式 机器学习/深度学习 测试技术
设计模式转型:从传统同步到Python协程异步编程的实践与思考
【7月更文挑战第15天】探索从同步到Python协程异步编程的转变,异步处理I/O密集型任务提升效率。async/await关键词定义异步函数,asyncio库管理事件循环。面对挑战,如思维转变、错误处理和调试,可通过逐步迁移、学习资源、编写测试和使用辅助库来适应。通过实践和学习,开发者能有效优化性能和响应速度。
46 3
|
3月前
|
调度 Python
揭秘Python并发编程核心:深入理解协程与异步函数的工作原理
【7月更文挑战第15天】Python异步编程借助协程和async/await提升并发性能,减少资源消耗。协程(async def)轻量级、用户态,便于控制。事件循环,如`asyncio.get_event_loop()`,调度任务执行。异步函数内的await关键词用于协程间切换。回调和Future对象简化异步结果处理。理解这些概念能写出高效、易维护的异步代码。
45 2