如何加入 Kotlin SupervisorJob
How to join a Kotlin SupervisorJob
我正在尝试处理数据对象树。每个树叶都应该通过使用协程的函数进行处理。整个过程应该使用固定大小的线程池来完成。
所以我想到了这个:
val node = an instance of WorkspaceEntry (tree structure)
val localDispatcher = newFixedThreadPoolContext(16)
fun main() {
val job = SupervisorJob()
val scope = CoroutineScope(localDispatcher + job)
handleEntry(node, scope)
runBlocking {
job.join()
}
}
handleEntry 方法递归地在主管中为每个树叶启动一个子作业。
主管的子作业全部成功完成,但从未加入 returns。我理解错了吗?
编辑:HandleEntry 函数
private fun handleEntry(workspaceEntry: WorkspaceEntry, scope: CoroutineScope) {
if (workspaceEntry is FileEntry) {
scope.launch {
FileTypeRegistry.processFile(workspaceEntry.fileBlob)
}
} else {
workspaceEntry.children.forEach { child -> handleEntry(child, scope) }
}
}
似乎用于创建 CoroutineContext
的 Job
(在你的例子中是 SupervisorJob
)并不是为了等待子协程完成,所以你不能使用 job.join()
。我猜 Job
的主要目的是取消子协程。将 runBlocking
块更改为以下内容将起作用:
runBlocking {
job.children.forEach {
it.join()
}
}
您混合了两个角色:
- 在协程范围内找到的主作业永远不会自行完成,用于控制其他一切的生命周期
- 工作单元对应的工作,可能分解为更多的子工作
两者都需要,像这样:
val masterJob = SupervisorJob()
val scope = CoroutineScope(localDispatcher + masterJob)
val unitOfWork = scope.launch { handleEntry(node, scope) }
runBlocking { unitOfWork.join() }
上面的代码并没有真正激发 master job 的存在,因为你只是从它开始了一个 child job,但它可能在更广泛的情况下有意义,你有一些背景可以从中启动许多工作, 并希望能够写
masterJob.cancel()
在完成之前取消一切。
我正在尝试处理数据对象树。每个树叶都应该通过使用协程的函数进行处理。整个过程应该使用固定大小的线程池来完成。
所以我想到了这个:
val node = an instance of WorkspaceEntry (tree structure)
val localDispatcher = newFixedThreadPoolContext(16)
fun main() {
val job = SupervisorJob()
val scope = CoroutineScope(localDispatcher + job)
handleEntry(node, scope)
runBlocking {
job.join()
}
}
handleEntry 方法递归地在主管中为每个树叶启动一个子作业。
主管的子作业全部成功完成,但从未加入 returns。我理解错了吗?
编辑:HandleEntry 函数
private fun handleEntry(workspaceEntry: WorkspaceEntry, scope: CoroutineScope) {
if (workspaceEntry is FileEntry) {
scope.launch {
FileTypeRegistry.processFile(workspaceEntry.fileBlob)
}
} else {
workspaceEntry.children.forEach { child -> handleEntry(child, scope) }
}
}
似乎用于创建 CoroutineContext
的 Job
(在你的例子中是 SupervisorJob
)并不是为了等待子协程完成,所以你不能使用 job.join()
。我猜 Job
的主要目的是取消子协程。将 runBlocking
块更改为以下内容将起作用:
runBlocking {
job.children.forEach {
it.join()
}
}
您混合了两个角色:
- 在协程范围内找到的主作业永远不会自行完成,用于控制其他一切的生命周期
- 工作单元对应的工作,可能分解为更多的子工作
两者都需要,像这样:
val masterJob = SupervisorJob()
val scope = CoroutineScope(localDispatcher + masterJob)
val unitOfWork = scope.launch { handleEntry(node, scope) }
runBlocking { unitOfWork.join() }
上面的代码并没有真正激发 master job 的存在,因为你只是从它开始了一个 child job,但它可能在更广泛的情况下有意义,你有一些背景可以从中启动许多工作, 并希望能够写
masterJob.cancel()
在完成之前取消一切。