首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我不能在kotlin协程中取消作业?

在Kotlin协程中取消作业的原因是因为协程的取消是基于协作的,而不是强制性的。当你在协程中调用取消操作时,实际上是向协程发送了一个取消请求,但是协程本身需要在适当的时机检查取消请求并作出响应。

Kotlin协程中的取消操作是通过协程的CancellationException异常来实现的。当协程被取消时,它会抛出CancellationException异常,你可以在协程的代码中捕获这个异常并做出相应的处理。

然而,取消操作只是一个请求,协程可以选择是否响应这个请求。在协程的执行过程中,它可以通过检查isActive属性来判断是否有取消请求。如果isActive为false,表示有取消请求,协程可以选择终止执行并抛出CancellationException异常。

但是,如果你在协程中使用了阻塞操作,比如调用了一个阻塞的网络请求或者执行了一个耗时的计算任务,那么协程就无法及时检查取消请求。这是因为阻塞操作会阻塞协程的执行,直到操作完成或超时。在这种情况下,协程无法及时响应取消请求,因此取消操作会被忽略。

为了解决这个问题,Kotlin提供了挂起函数withContext和suspendCancellableCoroutine。这些函数可以在协程中使用,以确保在执行阻塞操作时能够及时响应取消请求。通过使用这些函数,你可以在协程中进行阻塞操作,并在取消请求时立即中断操作。

总结起来,你不能在Kotlin协程中取消作业是因为协程的取消是基于协作的,而不是强制性的。协程需要在适当的时机检查取消请求并作出响应。如果在协程中使用了阻塞操作,协程无法及时响应取消请求。为了解决这个问题,可以使用Kotlin提供的挂起函数withContext和suspendCancellableCoroutine来确保在执行阻塞操作时能够及时响应取消请求。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云函数计算(云原生无服务器计算服务):https://cloud.tencent.com/product/scf
  • 腾讯云云数据库 MySQL 版(云原生数据库服务):https://cloud.tencent.com/product/cdb
  • 腾讯云云服务器(云原生计算服务):https://cloud.tencent.com/product/cvm
  • 腾讯云对象存储(云原生存储服务):https://cloud.tencent.com/product/cos
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Kotlin 启动 ⑥ ( 生命周期状态 | 新创建 New | 活跃 Active | 完成 Completing | 已完成 Completed | 取消 | 已取消 )

获取当前是否处于 已完成状态 ; 取消 Canceling 已取消 Cancelled : 通过调用 Job#isCancelled 获取当前是否处于 取消状态 ; 之前的博客 【Kotlin ...】启动 ④ ( 启动模式 | 构建器启动模式参数 | DEFAULT 模式 | ATOMIC 模式 | LAZY 模式 | UNDISPATCHED 模式 ) , 提到的 取消 后..., 进入 取消响应状态 , 需要 先进入 取消 Canceling 状态 , 然后再进入 已取消 Cancelled 状态 ; 三、生命周期状态改变 ---- 通过 launch 或 async...完成分支 : 当有 子 完成时 , 会进入 完成 Completing 状态 , 此时会等待其它子执行完毕 , 如果 所有的子都执行完毕 , 则进入 已完成 Completed 状态...; 取消分支 : 调用 Job#cancel() 函数 取消 , 会进入到 取消 Canceling 状态 , 此时不会立刻取消 , 因为该可能还有多个子 , 需要等待 所有子取消

63010

Kotlin 异常处理 ⑤ ( 异常传播的特殊情况 | 取消示例 | 子抛出异常后父处理异常时机示例 | 异常聚合 | 多个子抛出的异常会聚合到第一个异常 )

文章目录 一、异常传播的特殊情况 1、取消示例 2、子抛出异常后父处理异常时机示例 二、异常聚合 ( 多个子抛出的异常会聚合到第一个异常 ) 一、异常传播的特殊情况 ---- 在...【Kotlin 异常处理 ① ( 根异常处理 | 自动传播异常 | 在体捕获异常 | 向用户暴露异常 | 在 await 处捕获异常 | 非根异常处理 | 异常传播特性 ) 博客中介绍到... 运行时 , 产生异常 , 会将异常 传递给 父 , 父会执行如下操作 : ① 取消 : 不仅仅取消产生异常的子 , 该父下所有的子都会取消 ; ② 取消 : 将父本身取消...父 进行处理 ; 如果 父 有多个子 , 多个子 都抛出异常 , 父会等到 所有子 都执行完毕会后 , 再处理 异常 ; 1、取消示例 在下面的代码 , 在 父...主线程 一直占用线程 , 子无法执行 ; 子执行起来后 , 取消 , 此时 在子 , 会抛出 CancellationException 异常 , 该异常不会传递到 父 ,

71110

Kotlin 取消 ② ( CPU 密集型任务取消 | 使用 isActive 判定状态 | 使用 ensureActive 函数取消 | 使用 yield 函数取消 )

一、CPU 密集型任务取消 ---- 在 , 定义在 kotlinx.coroutines 包下的 suspend 挂起函数 是可以取消的 ; 但是有一种任务 , CPU 密集型任务..., 大量的临时数据会丢失 , 因此在 , 无法直接取消 CPU 密集型任务 , 这是对的保护措施 ; CPU 密集型任务取消示例 : 在下面的 任务 , 循环 10000000...Log.i(TAG, "退出作用域") } } } 执行结果 : 在执行任务过程 , 取消 , 但是没有取消成功 , 自动执行完毕 ; 18:45:33.896...") } } } 声明周期状态 参考 【Kotlin 启动 ⑥ ( 生命周期状态 | 新创建 New | 活跃 Active | 完成 Completing...* * 如果作业不再活动,则抛出[CancellationException]。 * 如果作业取消,则抛出异常包含原始的取消原因。

1K20

Kotlin实现原理:CoroutineScope&Job

今天我们来聊聊KotlinCoroutine。 如果你还没有接触过,推荐你先阅读这篇入门级文章What? 你还不知道Kotlin Coroutine?...Kotlin实现原理:Suspend&CoroutineContext 如果你已经接触过,相信你都有过以下几个疑问: 到底是个什么东西?...通过它的结构,我们可以认为它是提供CoroutineContext的容器,保证CoroutineContext能在整个协运行传递下去,约束CoroutineContext的作用边界。...val secondChild = launch { firstChild.join() // 取消了第一个子作业且没有传播给第二个子作业...-> Unit 这个cause有三种情况分别为: is null: 正常执行完毕 is CancellationException: 正常取消,并非异常导致的取消 Otherwise: 发生异常

1.6K40

Kotlin 的上下文和调度器介绍-Dispatchers

介绍 的上下文通常是CoroutineContext类型为代表。这个类型是被定义在Kotlin的标准库。 在,上下文是各种不同元素的集合。而其中主导作用的元素就是Job。...挂起后,它恢复线程,而这完全由被调用的挂起函数来决定。非受限的调度器非常适用于执行不消耗 CPU 时间的任务,以及更新局限于特定线程的任何共享数据(如UI)的。...isActive println(s) } //输出 true 说明当前的对象是活动的。 而为什么要添加“?” 那是因为对象可能为null。...并且这个新的Job对象将会成为父的子Job对象。 当一个父取消的时候,所有它的子也会被递归的取消。 但是,当使用 GlobalScope 来启动一个时,则新作业没有父作业。...延迟一秒钟来看看发生了什么 println("main: 整个协全部取消后") } //输出 job1: 运行在GlobalScope启动的 job2: 是一个父启动的子对象

36110

Coroutine()(一)

其实GlobalScope.launch可以通过Thread来替代,但要注意delay是一个特殊的 挂起函数 ,它不会造成线程阻塞,但是会 挂起 ,并且只能在中使用。...因为一段代码必须协作才能被取消 取消是 协作 的。一段代码必须协作才能被取消。 所有 kotlinx.coroutines 的 挂起函数 都是 可被取消的 。...job.cancelAndJoin() // 取消作业并且等待它结束 println("main: Now I can quit.") } 但是注意,finally 不能有挂起函数。...这是因为在被取消 CancellationException 被认为是执行结束的正常原因。 然而,在这个示例我们在 main 函数中正确地使用了 withTimeout。...当调用 launch { …… } 时传参数,它承袭了当前的上下文(以及调度器)。

80710

即学即用Kotlin -

前言 上周在内部分享会上大佬同事分享了关于 Kotlin 的知识,之前有看过 Kotlin 的一些知识,以为自己还挺了解的,结果......Kotlin - 基础篇》 《抽丝剥茧Kotlin - Flow篇》 目录 一、基础 1....显然,我们不能在 Activity 调用 GlobalScope,这样可能会造成内存泄漏,看一下如何自定义作用域,具体的步骤在注释已给出: class MainActivity : AppCompatActivity...协作取消 Flow 采用和协一样的协作取消,也就是说,Flow 的 collect 只能在取消的挂起函数挂起的时候取消,否则不能取消。...将会在下一篇文章中和大家讨论的原理,欢迎大家关注。 学习kotlin 还是很有必要的,我们团队在开发新的功能的时候,也全部选择了 Kotlin

1.5K20

【翻译】深入 Kotlin

将会指导你使用相关的基本示例,并观察背后到底发生了什么。 为什么这种解决方案非常有必要? 在现代应用程序开发,处理多线程任务是不可避免的工作。...在 C# async 和 await 都是关键字 在 C# async 函数只能返回一个 Task 实例或者返回空 如果你仔细观察的这个例子,你会看到在 Kotlin , launch{}...通常,一个坐落在一个实际的线程池当中,专门用于后台任务的执行操作,这也就是为什么如此高效的原因。它只会在需要的时候才会使用系统资源。...在上面那个例子是在 UI 这个协的上下文中使用 launch 函数,来自于 Anko 库。...在那种特定上下文的情形下,调用一个可以保证与 UI 相关连的代码(比如设置标签的文本)都能在 UI 线程中被调用。 第二个参数 start 是指明何时应该开始执行。

1.4K10

kotlin--入门

到目前为止没有一个具体的定义,但很多语言都有,但每个语言又有所不同,官方说基于线程,是轻量级的线程。在我看来,是一种趋势,它让我们从繁琐的多线程释放出来,提高我们的编写代码的效率。...人类的懒惰有了现在各种便利的东西,例外。...更像是一个管理者的秘书,它让我们从复杂的逻辑得到解放,只需要告诉秘书执行流程,其他的都交由秘书安排 以上就是的理解,接下来来学习如何使用kotlin 一、实现异步任务相同功能 如果说我们有一个耗时操作...1.取消任务,当某项任务不需要执行了,取消它 2.追踪任务,某项任务正在执行,追踪它 3.发出错误信号,当失败时,发出错误信号表明有错误产生 CoroutineScope 定义必须指定其...销毁,还是会运行 2.MainScope:在Activity中使用,可以在onDestroy取消 3.ViewModelScope:只能在ViewModel中使用,绑定ViewModel的生命周期

58810

Kotlin 学习笔记(四)—— 的基础知识,面试官的最爱了~

对 Jetpack Compose 感兴趣的同学可以看一下的另一个笔记系列—— Jetpack Compose 学习笔记。这次咱来看看 Kotlin 的基础知识。 1....要说上下文在我们的开发如何使用,找了下网上的一些资料,提到较多的就是异常的捕获了。...这也是为什么我们可以在中用写同步代码的思想,去写异步的逻辑。...但的知识远不止这些,希望此篇能起到抛砖引玉的作用,希望大家能在项目中使用,你会发现,用了就真的回不去了~ 参考文献 极客时间 Kotlin 系列课程; 张涛 《Kotlin 核心编程》; 霍丙乾...今天把它的皮给扒了 https://rengwuxian.com/kotlin-coroutines-2/ ;Hugo(谢晨成) Kotlin :简单理解 runBlocking, launch

1.4K30

Kotlin 】Flow 异步流 ⑤ ( 流的上下文 | 上下文保存 | 查看流发射和收集的 | 不能在不同执行流的发射和收集操作 | 修改流发射的上下文 | flowOn函数 )

文章目录 一、流的上下文 1、上下文保存 2、流收集函数原型 3、流发射函数原型 4、代码示例 - 查看流发射和收集的 5、代码示例 - 不能在不同执行相同流的发射和收集操作 二、修改流发射的上下文...的代码 , 收集元素操作在执行 , 流构建器 也同样在相同的运行 ; 流收集元素 和 发射元素 在相同的上下文中 的 属性 , 称为 上下文保存 ; 2、流收集函数原型 Flow#collect...kim.hsl.coroutine I/System.out: 1 2022-12-23 14:29:07.940 17484-17484/kim.hsl.coroutine I/System.out: 2 5、代码示例 - 不能在不同执行相同流的发射和收集操作...在流构建器 , 将代码定义在如下执行 , 使用 Dispatchers.IO 调度器 , 也就是在子线程执行 ; withContext(Dispatchers.IO){} 在流收集时..., 在 使用 runBlocking 将主线程包装后的 , 收集元素 , 在主线程执行 ; runBlocking {} 代码示例 : package kim.hsl.coroutine

89110

利用Kotlin实现简单的异步加载详解

因此在实际的开发通常把耗时操作放在一个新的线程(比如从网络获取数据,从SD卡读取图片等操作),但是呢在androidUI的更新只能在UI主线程中进行更新,因此当我们在非UI线程执行某些操作的时候想要更新...在本篇文章想给大家分享的是使用Kotlin的Coroutine()来实现耗时操作的异步加载,现在有RxJava这么屌的库我们为什么还要了解这个呢?...取消 在上边的例子我们返回了一个Job类型的对象job。通过调用job.cancel()我们能够取消一个。例如当我们退出当前Activity的时候,图片还没有加载完。...一旦Activity的onDestroy方法被调用的时候,我们在load()函数添加的lifecycle观察者将会取消第一个,也会使第二个取消,避免block()被调用。...上边的代码可以被应用到任何别的需要使用异步调用并将值转递到主线程的操作。和RxJava这种框架比起来Kotlin可能没有它那么强大。但是Kotlin可读性更强,也更简单。

2K20

kotlin 入门教程

但是认为这种比喻不对,更好的解释是kotlin其实是 kotlin 线程池中的一个任务(Task);我们能执行操作,其实是因为调用了框架的接口,该框架是对线程池的进一步封装。...明白这一点后,你可能会问,为什么kotlin要重复造轮子,java线程池不好吗?kotlin相对于我们使用java线程池有什么优势吗?...为什么直接使用Java线程池 这里需要提前说明一下,kotlin 封装的线程池与 java 的线程池是不一样的。...至于为什么提供的挂起函数,像delay,可以自动响应取消呢?...这是因为它们会自动检测当前是否已经被取消了,如果已经被取消了,就会抛出 CancellationException 异常,从而终止当前的异常的传播 之前讲过存在父子结构。

15110

Kotlin | 是什么?

很高兴,你终于追寻这个问题了,也许你正感到迷茫,各路大神对的理解不一,有人说它是线程框架,有人说它比线程更轻,希望这篇博文可以帮你从另一个角度简单理解。...所以请打开Kotlin中文网。很多人说kotlin官网教程很不详细,其实不然,kotlin中文网教程很详细。 回到正题: 什么是?...所以我希望大家刚入手时,多从语言角度去理解。 那么,是什么? 就是一个基于Kotlin语法的异步框架,它可以使开发者以同步的方式,写成异步的代码,而无需关注多余操作。...为什么test 的suspend 标志是黑的? 继续看截图 挂起函数为什么能在挂起函数中使用呢?? 我们再继续往下看:看一下java字节码 这个 Continuation是什么呢?...挂起函数为什么能在挂起函数中使用呢? 因为普通函数参数并没有带 Continuation啊,相当于没有挂起点,编译器无法判断,所以此时会报错。 为什么test 的suspend 标志是黑的?

56610

Kotlin | 使用手册(不间断更新)

Kotlin作为Kotlin核心的一个组件,上手成本并不高,下面的demo都是参照官网的例子过了一遍。 Kotlin中文网。 其中的Flow大家可以多花点时间,还是挺有意思的。...所以在实际应用,我们更推荐 : 在执行操作所在指定作用域内启动,而非随意使用 取消与超时 cancelAndJoin 取消一个并等待结束 runBlocking {...} 在finally重新挂起 在我们实际应用,可能需要在finally重新挂起一个被取消,所以可以将相应的代码包装在 **withContext(NoCancellable)**...main-抛出异常 注意:如果其中一个子失败,则第一个 playGame 和等待的父都会被取消 上下文和调度器 总是运行在以 coroutineContext 为代表的上下文中,上下文是各种不同元素的集合...,将直接运行在当前线程 子 当一个被其他在 CoroutineScope 启动时,它将通过 CoroutineScope.CoroutineContext 来承袭上下文,并且这个新将成为父的子作业

2.3K20

知识点 | ViewModel 四种集成方式

ViewMode 与 Kotlin : viewModelScope 于 Lifecycle 的 2.1.0 版本时加入 只支持 Kotlin Android 平台上的 通常情况下,我们使用回调...如果您不了解,这里有一系列很棒的博客《在 Android 开发中使用》以及 codelab: 在 Android 应用中使用 Kotlin 以供参考。...CoroutineScope 可以持续跟踪的执行,它可以被取消。当 CoroutineScope 被取消时,它所跟踪的所有都会被取消。...上面的代码使用了 GlobalScope,正如我们推荐随意使用全局变量一样,这种方式通常推荐使用。所以,如果想要使用,您要么限定一个作用域 (scope),要么获得一个作用域的访问权限。...时,使用 viewModelScope 来让在 ViewModel 被销毁时自动取消

2.5K20

Kotlin 总结

不过,我们学习 Kotlin ,一开始确实可以从线程控制的角度来切入。因为在 Kotlin 的一个典型的使用场景就是线程控制。...但在 Android 开发同样推荐这种用法,因为它的生命周期会和 app 一致,且不能取消(什么是取消后面会讲)。...suspend 是有暂停的意思,但我们在应该理解为:当线程执行到的 suspend 函数的时候,暂时继续执行代码了。...因为你这个函数实质上并没有发生挂起,那你这个 suspend 关键字只有一个效果:就是限制这个函数只能在里被调用,如果在非的代码调用,就会编译不通过。...很可能因为你看过的教程都是错的 2,Kotlin 的挂起好神奇好难懂?今天把它的皮给扒了 3,到底什么是「非阻塞式」挂起?真的更轻量级吗?

3K11

关于 Kotlin Coroutines, 你可能会犯的 7 个错误

但是,发现了许多开发者在使用时会犯一些通用性的错误。 1. 在使用时实例化一个新的 Job 实例 有时候你会需要一个 job 来对进行一些操作,例如,稍后取消。...CoroutineScope 运行这个协,然后取消作用域而不是的 job 。...为什么会这样? 原来,为了让异步/同步代码更加安全,提供了革命性的特性 —— “结构化并发” 。“结构化并发” 的一个机制就是:当作用域被取消时,就取消该作用域中的所有。...尝试使用 try/catch 来处理的异常 的异常处理很复杂,花了相当多的时间才完全理解,并通过 博客[8] 和 讲座[9] 向其他开发者进行了解释。...还作了一些 图[10] 来总结这个复杂的话题。 关于 Kotlin 异常处理最不直观的方面之一是,你不能使用 try-catch 来捕获异常。

91120
领券