首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin平行协同线

Kotlin平行协同线
EN

Stack Overflow用户
提问于 2017-11-10 20:05:41
回答 2查看 6.7K关注 0票数 4

从不同的协同器中保存多个作业实例是否可以接受。假设我想一次运行两个协同线,它们是不相关的,不能在一个协同线中运行,但我希望它们并行运行。在Android中,我应该保存作业实例,以便可以在onDestroy方法中取消作业。将每一份工作分别保存在一个列表中是可以接受的,还是我违反了某种规则?我知道在RX中他们有订阅,为什么在Kotlin Coroutines中没有类似的呢?

代码语言:javascript
复制
val jobList = arrayListOf<Job>()

fun startJob1() {
    jobList.add(launch {
        //do some work
    })

fun startJob1() {
    jobList.add(launch {
        //do some other unrelated work
    })

override fun onDestroy() {
    super.onDestroy()
    cancelAllActiveJobs(jobList)
}

这种类型的体系结构对协同工作有意义吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-11 10:14:57

您可以保存启动的Job对象列表,但也可以使用可用的父-子作业层次结构来管理和保存已启动的作业列表。

因此,首先,您不必定义作业列表,而是定义对父作业的引用:

代码语言:javascript
复制
val job = Job()

然后,每次你看到一个新的合作关系,你就让它成为这项工作的孩子:

代码语言:javascript
复制
fun startJob1() {
    launch(job) { // make it a child
        //do some work
    }
}

fun startJob1() {
    launch(job) { // make it a child
        //do some other unrelated work
    }
}

最后,当需要销毁对象并取消所有作业时,只需取消父作业。

代码语言:javascript
复制
override fun onDestroy() {
    super.onDestroy()
    job.cancel()
}

这种分配的优点是任务列表是自动管理的。新的协同可以启动并添加到父作业中,当它们完成时,它们会自动从父作业中移除自己。

您可以在指南的相应部分阅读更多内容:https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#cancellation-via-explicit-job

票数 6
EN

Stack Overflow用户

发布于 2017-11-10 20:36:35

这是完全可行的,也没什么特别的。看看这个简单的例子,它同时创造了100000个就业机会:

代码语言:javascript
复制
val jobs = List(100_000) { // launch a lot of coroutines and list their jobs
        launch {
            delay(1000L)
            print(".")
        }
    }
 jobs.forEach { it.join() } 

为了使作业可取消,它本身必须检查它是否已从外部取消,您可以在活动状态:while (isActive)上执行一个循环。

下面是一个示例,其中两个作业随后被取消:

代码语言:javascript
复制
fun main(args: Array<String>) = runBlocking {
    val startTime = System.currentTimeMillis()
    val jobs = arrayListOf<Job>()
    jobs += launch {
        var nextPrintTime = startTime
        var i = 0
        while (isActive) { // check if still active
            if (System.currentTimeMillis() >= nextPrintTime) {
                println("Job1: Sleeping ${i++} ...")
                nextPrintTime += 500L
            }
        }
    }

    //another job
    jobs += launch {
        while (isActive) { // check if still active
            if (System.currentTimeMillis() >= 42) {
                println("Job2: Sleeping 42 ...")
                delay(500L)
            }
        }
    }
    delay(1300L) // delay a bit
    println("main: Cancelling the sleeping job!")
    jobs.forEach { it.cancelAndJoin() } // cancels the job and waits for its completion
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47230334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档