Kotlin suspendCancellCoroutine 笔记

suspendCancellableCoroutine 是 Kotlin 协程提供的一个底层挂起函数,用于将基于回调的异步 API 封装为挂起函数,同时支持协程的取消机制 。它比 suspendCoroutine 更强大,因为它允许在协程被取消时清理资源或停止正在进行的操作。


1. 作用

  • 桥接回调式 API :将传统的回调(如 onSuccess/onFailure)转换为挂起函数,让调用方可以用同步风格写异步代码。
  • 响应取消 :当启动协程的协程作用域被取消时,suspendCancellableCoroutine 可以感知取消事件,并执行清理操作(如关闭网络连接、取消异步任务),避免资源泄漏。

2. 函数签名

kotlin 复制代码
suspend fun <T> suspendCancellableCoroutine(
    block: (CancellableContinuation<T>) -> Unit
): T
  • 它挂起当前协程,直到通过 continuation.resume(...) 或 continuation.resumeWithException(...) 恢复。
  • 参数 block 接收一个 CancellableContinuation<T> 对象,该对象除了提供 resume 方法外,还增加了取消相关的功能。

3. 与 suspendCoroutine 的区别

特性 suspendCoroutine suspendCancellableCoroutine
取消监听 ❌ 无法感知协程取消 ✅ 可以注册取消回调
资源清理 ❌ 需要手动处理(如用 finally) ✅ 在取消回调中安全释放资源
并发处理 基础功能 额外提供原子性操作(如 invokeOnCancellation)

4. 典型用法

示例:将回调式 API 封装为挂起函数

假设有一个基于回调的网络请求:

kotlin 复制代码
interface Callback {
    fun onSuccess(result: String)
    fun onFailure(error: Throwable)
}

fun makeRequest(callback: Callback) {
    // 模拟异步请求
    Thread.sleep(1000)
    callback.onSuccess("Data")
}

使用 suspendCancellableCoroutine 封装:

kotlin 复制代码
suspend fun fetchData(): String = suspendCancellableCoroutine { continuation ->
    makeRequest(object : Callback {
        override fun onSuccess(result: String) {
            // 恢复协程,返回结果
            continuation.resume(result)
        }
        override fun onFailure(error: Throwable) {
            // 恢复协程并抛出异常
            continuation.resumeWithException(error)
        }
    })

    // 注册取消回调:如果协程被取消,可以取消请求
    continuation.invokeOnCancellation {
        // 清理资源,例如取消网络请求、关闭流等
        cancelRequest()
    }
}

取消处理的关键点

  • invokeOnCancellation:注册一个回调,当协程被取消时执行。通常在这里释放资源或取消底层操作。
  • 如果底层 API 本身支持取消(如返回一个 Cancellable 对象),可以在这里调用其取消方法。

5. 注意事项

  • 原子性恢复 :CancellableContinuation 提供了 resume 的原子性保证,但开发者仍需确保不要重复调用 resume。
  • 已取消状态的检查 :在调用 resume 前,可以使用 continuation.isActive 判断协程是否仍处于活跃状态,避免不必要的操作。
  • 取消传播 :如果协程被取消,挂起点会抛出 CancellationException,调用方需要适当处理(通常由上层协程作用域统一处理)。

6. 高级功能

  • 不可取消的挂起 :如果确实不需要取消,或者无法响应取消,可以使用 suspendCoroutine。但通常推荐使用 suspendCancellableCoroutine 以提供更好的协作式取消。
  • 调用栈信息 :CancellableContinuation 还保留了挂起点的调用栈,便于调试。

总结

suspendCancellableCoroutine 是编写自定义挂起函数的核心工具,尤其适用于需要与取消机制协同工作的回调式 API。通过它,你可以将任何异步操作无缝集成到 Kotlin 协程的取消体系中,实现资源的安全管理和高效的并发控制。

相关推荐
小程故事多_803 小时前
从 Tokenizer 到 Next Token,穿透数据流,完整理解 Transformer 底层逻辑
android·深度学习·transformer
三少爷的鞋6 小时前
Android 协程实践:为什么不应将 `supervisorScope` 作为常规方案
android
承渊政道7 小时前
【从零开始大模型开发与微调:基于PyTorch与ChatGLM】(从ChatGLM本地化到LoRA、PEFT的高级微调)
android·人工智能·pytorch·chatglm·本地化部署·大模型开发与微调
2601_962885729 小时前
如何用 Python 判断一只股票“追涨”还是“抄底”更有效?
android·开发语言·python
素师良码9 小时前
第10篇:屏ESD Check内核逻辑驱动代码完整拆解
android
高晶9 小时前
Android 短信收发模块从零到实战:权限配置、界面设计、发送接收与兼容性适配全攻略
android·程序员
随遇丿而安9 小时前
第18周:ViewModel 基础功能 + 架构优化
android
问心无愧051312 小时前
[GXYCTF2019]Ping Ping Ping
android·笔记
事圆则缓12 小时前
Kotlin 异步与并发:从一次搜索请求走到状态流
android·开发语言·kotlin
帅得不敢出门13 小时前
Android Framework定制卸载确认窗口
android