协程取消难点剖析与超时机制探析

协程取消难点剖析:

在上一次https://www.cnblogs.com/webor2006/p/11797374.html学习了协程的取消,本次继续对取消相关的东东进行进一步学习。

先回顾一下上一次协程取消的例子,因为接下来的实验会依据它来进行说明:

好,接下来咱们来改造一下:

也就是在finally里中调用了delay这个挂起函数了,那运行结果会如何呢?下面来瞅下:

呃,貌似结果有点让人意外呀:

其实这里是有原因的,下面先来将其理论描述一下:

当我们在协程的finally块中使用了挂起函数时,会导致出现CancellationException异常,原因在于运行着该代码块的协程已经取消了。通常情况下,这并不会产生什么问题,因为大多数关闭操作(比如说取消一个job,关闭网络连接等)通常都是非阻塞的,并不需要使用挂起函数;然而,在极少数情况下,当我们在一个取消的协程中运行挂起操作时,我们可以将相应的代码放置到withContext(NonCancellable) {}当中,在这种结构中,我们实际上使用了withContext函数与NonCancellable上下文。

言外之意就是:

那如果要完整执行我们想要的代码该如何搞呢?也就按理论描述所说,放置在withContext代码块中,如下:

再来看结果:

完美的执行了我们想要的代码,也就是如果未来实际代码中在finally块中想要执行挂起函数时,则可以用这种方式来解决,下面咱们来大致瞅一下这个withContext:

我们在调用时传了一个“NonCancellable”:

那咱们瞅一下它:

协程超时机制:

对于超时机制在实际需求中也是很常见的,比如进行网络访问时,如果因为某些原因请求非常之慢,则超时机制就是必须要存在的,所以下面来学习一下在Kotlin中的超时机制,先来看一下它的理论:

我们在使用协程时,如果取消了协程,那么很大一部分原因都在于协程的执行时间超过了某个设定值;我们可以通过手工引用与协程对应的Job的方式来启动一个单独的协程用于取消这个协程【也就是调用cancelAndJoin】,不过Kotlin提供了一个内建的函数【withTimeout】来帮助我们又快又好地做到这一点。

咱们来用一下:

设置了1.9s的超时时间,然后执行逻辑是每400ms打印一下,那应该会打印5次,然后就会超过1.9s,那达到超时时间又会是啥效果呢,运行一下:

那如果不超时呢,应该代码就正常执行了,修改一下代码试一下:

下面大致瞅一下这个函数的定义:

其实它还有另一个类似的方法:

这个下次再来学习。

posted on 2019-12-09 12:59  cexo  阅读(551)  评论(0编辑  收藏  举报

导航