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 协程的取消体系中,实现资源的安全管理和高效的并发控制。

相关推荐
Jomurphys2 小时前
Android 优化 - R8 混淆
android
summerkissyou19873 小时前
Android-Audio-MediaPlayer和AudioTrack播放区别
android·audio
独自破碎E3 小时前
BISHI69 [HNOI2008]越狱
android·java·开发语言
Rhystt3 小时前
furryCTF题解|Web方向|ezmd5、猫猫最后的复仇
android·前端·web安全·web
测试工坊18 小时前
Android CPU 使用率采集入门:从原理到公式
android
恋猫de小郭18 小时前
iOS + AI ,国外一个叫 Rork Max 的项目打算替换掉 Xcode
android·前端·flutter
systeminof20 小时前
从静态到实时对抗:首例安卓Runtime AI病毒解析
android·人工智能
福大大架构师每日一题21 小时前
ComfyUI v0.14.2 发布:修复 Gemini/Nano banana 节点空白图像问题,全新 MIME 匹配机制登场
android·comfyui