UrK*_*UrK 4 design-patterns coroutine kotlin kotlin-coroutines
我的一个库中有一个数据管理器类。到目前为止,它一直与执行者合作并拥有自己的执行者。现在该类正在转换为协程。
当管理器必须异步初始化数据时,就会出现问题,如下例所示。为了执行挂起函数,对的调用suspendedInit必须包含在launch. 这里的问题是管理器没有自己的协程作用域。
有一些我正在看但不喜欢的:
DataManager构造函数并使用它。问题是用户DataManager尚不支持协程,因此没有自己的范围。DataManager实施CoroutineScope并创建自己的范围。正如文档所记录的那样,不鼓励这样做CoroutineScope。这个问题的推荐解决方案是什么?
class DataManager {
init {
suspendedInit()
}
private suspend fun suspendedInit() = withContext(Dispatchers.IO) {
/* some long asynchronous operations here */
}
}
Run Code Online (Sandbox Code Playgroud)
DataManager 实现 CoroutineScope 并创建自己的作用域。CoroutineScope 文档中不鼓励这样做。
如果初始程序DataManager有自己的执行程序,那么它很可能也有自己的生命周期,并以适当的方式关闭该执行程序。
在这种情况下,完全可以按照创建CoroutineScope执行器的方式创建自己的执行器(实际上它实际上可以基于您的初始执行器)。唯一不鼓励的情况是您没有正确处理作用域的生命周期:
CoroutineScope 应声明为具有明确定义的生命周期的实体的属性,负责启动子协程。
CustomScope 自定义使用的关键部分是取消它并结束生命周期。当不再需要启动协程的实体时,应使用 CoroutineScope.cancel 扩展函数。
class DataManager {
private val executor = TODO("original executor definition")
val coroutineScope = executor.asCoroutineDispatcher()
init {
coroutineScope.launch {
suspendedInit()
}
}
private suspend fun suspendedInit() = ...
fun close() {
// executor.shutdown() // <-- not needed anymore
coroutineScope.cancel()
}
}
Run Code Online (Sandbox Code Playgroud)
如果不需要独立的线程池,您也可以完全摆脱执行器。CoroutineScope(Dispatchers.IO)在这种情况下,您可以使用(如果您想要为所有协程使用 IO 调度程序)或CoroutineScope(Dispatchers.Default)(如果您打算启动主要受 CPU 限制的任务)来初始化作用域,并withContext(IO)在必要时使用。
| 归档时间: |
|
| 查看次数: |
2773 次 |
| 最近记录: |