关于coroutine的异常捕获和取消机制

embedded/2024/10/16 0:07:05/

https://www.youtube.com/watch?v=VWlwkqmTLHc&list=PLQkwcJG4YTCQcFEPuYGuv54nYai_lwil_&index=11

协程总结

抓不到的异常

如果我们在launch外面try catch 意图捕获异常的话

   //无法捕获异常导致奔溃private fun cannotCatchException() {lifecycleScope.launch {try {//外面catch不到的launch {//只能在这里面try catch,直接捕获throw Exception()}} catch (e: Exception) {e.printStackTrace()}}}

如果不是在抛出异常的地方直接捕获异常,那么在外面是捕获不到的,会直接导致应用奔溃

asyn不会奔溃

如果async中发生了异常,如果没有调用await,则程序不会奔溃

 private fun asyncWonCrash() {lifecycleScope.async {val string = async {delay(1000)throw Exception("error")}}}

我们在async中直接抛出异常,但是应用没有奔溃

但如果在launch中运行,需要再await的地方添加捕获,不然程序奔溃

  private fun asyncWonCrash() {val result = lifecycleScope.async {val string = async {delay(1000)throw Exception("error")"result"}println("linlian"+string.await())}lifecycleScope.launch {try {result.await()} catch (e: Exception) {e.printStackTrace()}}}

当时如果只是看到这里,以为就结束了!!!!

no,上面的这个异常捕获,有一个很大的陷阱,之前的文章也有提到

就是我们可能吧 cancellation exception也捕获了,导致协程任务无法取消!!!!

那一般是怎么处理了,可以根coroutinescope添加coroutineexception handler

    private val exceptionHander = CoroutineExceptionHandler { ctx, throwale ->println("handle exception $throwale")}private fun exceptionHandlerdemo() {lifecycleScope.launch(exceptionHander) {launch {throw Exception("error")}}}

这样内部子任务的异常都可以被捕获

协程的某个子任务异常了,那其他的任务会怎样呢?

那这个和所在的scope的类型有关,如果是个普通的sceop

当有一个子协程异常了,其他的协程也取消了

 private fun differentScope() {CoroutineScope(Dispatchers.Main).launch(exceptionHander) {launch {delay(300)throw Exception("linlian 1 failed")}launch {delay(500)println("linlian 2 success")}}}

但是像viewmodescope这些,还有globalscope,一般我们一个子协程异常,是不会影响到其他的协程的,这个是什么原因呢

viewmodel的源码中

val ViewModel.viewModelScope: CoroutineScopeget() {val scope: CoroutineScope? = this.getTag(JOB_KEY)if (scope != null) {return scope}return setTagIfAbsent(JOB_KEY,CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate))}
SupervisorJob()

Creates a supervisor job object in an active state. Children of a supervisor job can fail independently of each other.

互不影响

private fun differentScope() {CoroutineScope( Dispatchers.Main).launch(exceptionHander) {supervisorScope {launch {delay(300)throw Exception("linlian 1 failed")}launch {delay(500)println("linlian 2 success")}}}}

所以加上 supervisorScope ,任务2就不会因为任务1的异常而被影响,取消了。

另外如果cancellation exception被捕获的话,任务也不会取消,会一直运行下去


http://www.ppmy.cn/embedded/128146.html

相关文章

智能听诊器:宠物健康管理的革命

智能听诊器不仅仅是一个简单的监测工具,它代表了宠物健康管理的一次革命。通过收集和分析宠物的生理数据,智能听诊器能够帮助宠物主人和医生更好地理解宠物的健康需求,从而提供更加个性化的护理方案。 智能听诊器通过高精度的传感器&#xf…

人类与人工智能的和谐关系

人类与人工智能的和谐关系 打不过就加入吧,人类在人工智能为基础的智能机器面前 毫无优势可言,这方面的介绍 见我之前的文章《智能机器是世界上的新物种》 第一、人不要想着与机器对抗 人不要想着与机器竞争,或者是比赛,哪怕规则都是人类定的&#xf…

022 elasticsearch文档管理(添加、修改、删除、批处理)

文章目录 添加文档修改文档删除文档根据_id取文档使用批处理_bulk PortX: https://portx.online/zh MobaXterm: https://mobaxterm.mobatek.net/ FinalShell: http://www.hostbuf.com/ 添加文档 向索引中添加一行数据 使用json来表示 使用…

【DevOps工具篇】Docker的DNS原理

在使用 Docker 容器时,网络在实现容器与外界之间的通信方面起着至关重要的作用。容器网络的一个基本方面是 DNS(域名系统),它允许容器使用域名而不是依赖 IP 地址来发现彼此并相互通信。在本文中,我们将探讨 Docker DNS 以及它如何促进容器通信。 🔎 什么是 DNS? 域名…

微信小程序上传组件封装uploadHelper2.0使用整理

一、uploadHelper2.0使用步骤说明 uploadHelper.js ---上传代码封装库 cos-wx-sdk-v5.min.js---腾讯云,对象存储封装库 第一步,下载组件代码,放置到自己的小程序项目中 第二步、 创建上传对象,执行选择图片/视频 var _this th…

Spring Boot技术在医疗病历B2B交互中的实践与挑战

第6章 程序测试与评价 6.1 程序调试 在设计系统的过程中,存在一些错误是必然的。对于语句的语法错误,在程序运行时自动提示,并请求立即纠正,因此,这类错误比较容易发现和纠正。但另一类错误是在程序执行时由于不正确的…

nginx配置多个SSL证书实操记录

文章目录 [TOC](文章目录) 前言配置方式一配置方式二总结 前言 因为一些原因,客户需要更换域名和证书,而原有系统在用,包含一个APP,一个小程序,一个web站点。需要做到无感更换域名。查阅资料后发现nginx可以支持配置多…

外包干了5天,技术明显退步

我是一名本科生,自2019年起,我便在南京某软件公司担任功能测试的工作。这份工作虽然稳定,但日复一日的重复性工作让我逐渐陷入了舒适区,失去了前进的动力。两年的时光匆匆流逝,我却在原地踏步,技术没有丝毫…