Kotlin进阶-取消与超时

1.取消协程的执行

在一个⻓时间运行的应用程序中,你也许需要对你的后台协程进行细粒度的控制。比如说,一个用戶也许关闭了 一个启动了协程的界面,那么现在协程的执行结果已经不再被需要了,这时,它应该是可以被取消的。该 launch 函数返回了一个可以被用来取消运行中的协程的 Job:

image.png

一旦main函数调用了 job.cancel,我们在其它的协程中就看不到任何输出,因为它被取消了。这里也有一 个可以使 Job 挂起的函数 cancelAndJoin 它合并了对 cancel 以及 join 的调用。

2.取消是协作的

协程的取消是 协作 的。一段协程代码必须协作才能被取消。所有 kotlinx.coroutines 中的挂起函数都是 可被取消的 。它们检查协程的取消,并在取消时抛出 CancellationException。然而,如果协程正在执行计算任务,并且没有检查取消的话,那么它是不能被取消的,就如如下示例代码所示:

image.png

运行结果:

image.png

当协程可以被取消时,取消协程为什么没有抛出CancellationException异常呢?

image.png

3.使计算代码可取消

检查取消状态,

image.png

调用cancelAndJoin()时会改变isActive的值,所以while循环就会退出

运行结果:

image.png

4.在 finally 中释放资源

image.png

运行结果:

image.png

5.运行不能取消的代码块

在前一个例子中任何尝试在 finally 块中调用挂起函数的行为都会抛出 CancellationException,因为这里 持续运行的代码是可以被取消的。

image.png

运行结果:

image.png

在finally中执行挂起函数delay会抛出异常,所以运行结果只打印了job: I'm running finally1,没有打印job: I'm running finally2

通常,这并不是一个问题,所有良好的关闭操作(关闭一个文件、取消一个作 业、或是关闭任何一种通信通道)通常都是非阻塞的,并且不会调用任何挂起函数。然而,在真实的案例中,当你 需要挂起一个被取消的协程,你可以将相应的代码包装在 withContext(NonCancellable) {......} 中,并 使用 withContext 函数以及 NonCancellable 上下文,如下示例所示:

image.png

运行结果:

image.png

6.超时

在实践中绝大多数取消一个协程的理由是它有可能超时。当你手动追踪一个相关 Job 的引用并启动了一个单独 的协程在延迟后取消追踪,这里已经准备好使用 withTimeout 函数来做这件事。如下代码:

image.png

运行结果:

image.png

withTimeout 抛出了 TimeoutCancellationException ,它是 CancellationException 的子类。我们之前 没有在控制台上看到堆栈跟踪信息的打印。这是因为在被取消的协程中 CancellationException 被认为 是协程执行结束的正常原因。

由于取消只是一个例外,所有的资源都使用常用的方法来关闭。如果你需要做一些各类使用超时的特别的额外操作,可以使用类似 withTimeout 的 withTimeoutOrNull 函数,并把这些会超时的代码包装在 try {...} catch (e: TimeoutCancellationException) {...} 代码块中,而 withTimeoutOrNull 通过返回
null 来进行超时操作,从而替代抛出一个异常:

image.png

7.资源的异步超时

初始化资源时,如果在规定时间内资源没有初始化(获取资源)完成,则会抛出超时异常,之后的释放资源的操作就不会执行,这样就会导致内存泄漏,如下代码

image.png

如果运行的结果不为0,则表示有内存泄漏

如何避免这种内存泄漏呢?
将释放资源的操作放在finally中

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357

推荐阅读更多精彩内容