首页 > 技术文章 > 协程的取消关键技术分析及资源清理详解

webor2006 2019-11-05 11:26 原文

协程取消分析:

继续来学习协程相关的东东,这里主要是学习协程取消相关的知识,这个在实际开发的场景中都会用到的,比如说一个协程执行的时间比较长了不想让它再执行了则就有取消的需求,这里在正式撸码之前,先对Kotlin依赖的版本进行升一下级,先看一下目前所使用的版本:

这里咱们升级一下,改成这个版本:

为啥要升级呢?因为像之后还要继续学习协程相关的东东,其中未来会学习它的Channel通道相关的东东,在1.2.1这个版本还是一个试验性的版本,而在1.3.2已经做为正式的版本了,所有有必要升级一下便于更好的学习,改完之后则会进行下载,得稍等片刻,下载完了接下来就可以撸码了:

编译运行:

其流程比较好理解:

下面来瞅一下它的cancel()方法的说明:

所以咱们可以显示的指定一下这个参数,如下:

另外还有一个细节:

那既然这俩是需要成对来编写的,那有没有一种简化的方法能代替上面两句代码呢?答案是肯定的,如下:

 

看一下它的具体实现就秒懂了:

好,接下来再来看第二个例子,在编写之前先看个理论:

kotlinx.coroutines包下的所有挂起函数都是可取消的,他们会检查协程的取消状态,当取消时就会抛出CancellationException异常。不过,如果协程正在处于某个计算过程当中,并且没有检查取消状态,那么它就是无法被取消的。

好,下面用程序来理解上面的理论:

其中协程中的代码会不断在执行,并没有一个等待,为啥?

  

那结果是啥呢?运行一下:

呃,居然协程木有取消成功,这是为啥呢?其实这里要论证的就是刚才的这个理论:

那怎么能让其正常取消呢?这里又得先来看一下理论:

有两种方式可以让计算代码变为可取消的:

1、周期性地调用了一个挂起函数,该挂起函数会检测取消状态,比如说使用yield函数。

2、显示地检查取消状态。

这里用第二种方式,具体做法如下:

先看一下它的定义:

看一下它的官方说明:

好,运行一下,看是否如我们预期:

确实是如预期,但是!!为啥咱们之前写的那个程序我们没有使用这个属性也能自动取消呢,回忆一下:

 

为啥,咱们先来读一读它官方的文档说明就知晓了:

资源清理

先来理论:

使用finally来关闭资源,join与cancelAndJoin都会等待所有清理动作完成才会继续往下执行。” 

撸码来理解:

运行:

比较好理解,就不多解释了。

推荐阅读