从不同的协同器中保存多个作业实例是否可以接受。假设我想一次运行两个协同线,它们是不相关的,不能在一个协同线中运行,但我希望它们并行运行。在Android中,我应该保存作业实例,以便可以在onDestroy方法中取消作业。将每一份工作分别保存在一个列表中是可以接受的,还是我违反了某种规则?我知道在RX中他们有订阅,为什么在Kotlin Coroutines中没有类似的呢?
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)
}这种类型的体系结构对协同工作有意义吗?
发布于 2017-11-11 10:14:57
您可以保存启动的Job对象列表,但也可以使用可用的父-子作业层次结构来管理和保存已启动的作业列表。
因此,首先,您不必定义作业列表,而是定义对父作业的引用:
val job = Job()然后,每次你看到一个新的合作关系,你就让它成为这项工作的孩子:
fun startJob1() {
launch(job) { // make it a child
//do some work
}
}
fun startJob1() {
launch(job) { // make it a child
//do some other unrelated work
}
}最后,当需要销毁对象并取消所有作业时,只需取消父作业。
override fun onDestroy() {
super.onDestroy()
job.cancel()
}这种分配的优点是任务列表是自动管理的。新的协同可以启动并添加到父作业中,当它们完成时,它们会自动从父作业中移除自己。
您可以在指南的相应部分阅读更多内容:https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#cancellation-via-explicit-job
发布于 2017-11-10 20:36:35
这是完全可行的,也没什么特别的。看看这个简单的例子,它同时创造了100000个就业机会:
val jobs = List(100_000) { // launch a lot of coroutines and list their jobs
launch {
delay(1000L)
print(".")
}
}
jobs.forEach { it.join() } 为了使作业可取消,它本身必须检查它是否已从外部取消,您可以在活动状态:while (isActive)上执行一个循环。
下面是一个示例,其中两个作业随后被取消:
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
}https://stackoverflow.com/questions/47230334
复制相似问题