有没有办法重用Job实例?

阿托克

我正在探索在Android UI线程上下文中使用协同例程。contextJob按照《协程指南》 UI中所述进行了实施后台工作是从GUI开始的,我想在每次单击时重新启动它(停止当前正在运行的操作,然后重新启动)。

但是一旦取消的工作就无法重复使用,因此即使创建子工作:

 val job = Job(contextJob)

取消它并没有帮助,因为必须重新分配它。

有没有办法重用Job实例?

罗曼·伊里扎罗夫(Roman Elizarov)

一个工作有设计一个非常简单的生命周期。它的“已完成”状态是最终状态,与Android的“已销毁”状态非常相似Activity因此,如指南中所述,Job最好将父项与关联Activity当且仅当活动被销毁时,才应取消上级工作。由于无法重用已销毁的活动,因此您永远不会遇到重用其工作的需求。

推荐使用actor来启动每次单击的工作,因为它们可以帮助您避免不必要的并发。该指南显示了如何在每次单击时启动它们,但未显示如何取消当前运行的操作。

您需要Job结合使用的新实例,withContext以使代码块可以与其他所有内容分开取消:

fun View.onClick(action: suspend () -> Unit) {
    var currentJob: Job? = null // to keep a reference to the currently running job
    // launch one actor as a parent of the context job
    // actor prevent concurrent execution of multiple actions
    val eventActor = actor<Unit>(contextJob + UI, capacity = Channel.CONFLATED) {
        for (event in channel) {
            currentJob = Job(contextJob) // create a new job for this action
            try {
                // run an action within its own job
                withContext(currentJob!!) { action() }
            } catch (e: CancellationException) {
                // we expect it to be cancelled and just need to continue
            }
        }
    }
    // install a listener to send message to this actor
    setOnClickListener {
        currentJob?.cancel() // cancel whatever job we were doing now (if any)
        eventActor.offer(Unit) // signal to start next action when possible
    }
}

在取消其父项(附加到活动)之前,角色始终处于活动状态。演员等待点击,并action在每次点击时开始播放。但是,每次对an的调用action都包装在自己的JobusingwithContext块中,因此可以从其父作业中分别取消它。

请注意,此代码可以正常执行不可取消的操作或需要花费一些时间才能取消的操作。一个动作在取消时可能需要清理其资源,并且由于此代码使用了一个actor,因此它可以确保在开始下一个动作之前完成对上一个动作的清理。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

有没有办法使HTML可重用块?

有没有办法重用聚合步骤?

有没有办法使Oracle Job自身禁用?

有没有办法在代码中重用具有不同值的函数?

我有重复的代码 - 有没有办法扩展/重用 terraform 模块?

有没有办法重用具有不同结束参数的循环?

有没有办法让派生实例使用现有的基础实例

有没有办法在给定的int32_t上重用std :: atomic?

有没有办法在底层范围内重用if(...)条件的值?

有没有办法在keras中重用计算图的评估部分?

有没有办法在Redux中重用reducer逻辑?

有没有办法可以重用 EDN 中定义的键的值?

API 测试时,有没有办法在 JMeter 中跟踪 HATEOAS 链接/重用响应?

有没有办法在ELKI中将Optics算法的输出重用于Optics Xi?

有没有办法可以保存用户输入然后在 python 中重用它?

有没有办法验证 ILogger <T> 实例没有 LogError?

有没有办法从基本实例创建派生实例?

有没有办法在TypeScript中实例化受约束的泛型类型的实例?

有没有办法在编译时实例化所有c ++模板大小?

有没有办法连接到现有的商店实例

有没有办法通过 Ansible 的标签终止所有 EC2 实例?

vscode - 有没有办法创建 `vscode.TextEditor` 的实例?

有没有办法限制文件处理程序实例的数量?

有没有办法从实例获取平台和操作系统

有没有办法实例化可比较的数组,只是确定其长度

有没有办法判断MediaCodec实例是否已成功配置?

有没有办法只查看表对象的最后一个实例

即使其连接的实例失败,有没有办法保持ELB粘性会话?

有没有办法在CSS中编辑类的单个实例?