nha*_*man 3 kotlin kotlin-coroutines
我正在使用范围的类中执行一些工作:
class MyClass(val scope: CoroutineScope) {
private val state: StateFlow<Int> = someFlow()
.shareIn(scope, started = SharingStared.Eagerly, initialValue = 0)
fun save() {
scope.launch {
save(state.value)
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想在取消范围时进行清理。做这个的最好方式是什么?我可以想出这个,但这听起来不太稳定。
init {
scope.launch {
try { delay(10000000000000) }
finally { withContext(Noncancellable) { save(state.value) } }
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我修改了我的代码片段以更好地反映我正在做的事情。流state
每秒更新几次,当我调用该save()
方法时,我想将状态保存到磁盘(所以我不想每次状态更改时都这样做)。
接下来,我想在取消作用域时(即最后)保存状态。这就是我遇到麻烦的地方。
Jof*_*rey 10
据我所知,没有这样的“onCancellation”机制CoroutineScope
。但是,有Job.invokeOnCompletion。因此,如果您确实想这样做,您可以Job
从作用域的上下文中提取实例并在那里注册回调:
val job = scope.coroutineContext.job // this fails if there is no job
job.invokeOnCompletion { cause ->
if (cause is CancellationException) {
// that's a normal cancellation
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,可能存在没有作业的协程作用域,因此如果您使用此代码,请确保您没有使用如此奇特的作用域。
现在,一般情况下,在执行需要清理的代码时,可以就地“准备”清理。例如,使用带输入流use { ... }
或带块关闭资源finally
。这将在取消(或任何其他失败,顺便说一句)时自动兑现,因为范围的取消只会CancellationException
在运行的协程内生成 s。
解决此问题的另一种方法是在取消范围的同一位置进行所需的清理。
如果您确实想使用像当前并行协程这样的解决方法,您可以使用awaitCancellation而不是巨大的延迟:
init {
scope.launch {
try { awaitCancellation() }
finally { withContext(Noncancellable) { save(state.value) } }
}
}
Run Code Online (Sandbox Code Playgroud)
但我觉得它不太吸引人。
归档时间: |
|
查看次数: |
2919 次 |
最近记录: |