Kotlin 从CoroutineScope与SupervisorJob启动的作业是否也是SupervisorJob?

Kotlin 从CoroutineScope与SupervisorJob启动的作业是否也是SupervisorJob?,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,在下面的例子中。childJob是一份监督工作吗 val viewModelScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob()) val childJob = viewModelScope.launch {/* do something */} 或者类似的东西是必要的: val viewModelScope: CoroutineScope = CoroutineScope(Dispatchers.M

在下面的例子中。childJob是一份监督工作吗

val viewModelScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
val childJob = viewModelScope.launch {/* do something */}
或者类似的东西是必要的:

val viewModelScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
val childJob = viewModelScope.launch(SupervisorJob()) {/* do something */}

据我所知,SupervisorJob不会影响孩子们,因为它也会改变孩子们的行为,让孩子们像SupervisorJob一样,也就是说SupervisorJob的孩子们不能让父母的工作不及格,但如果孩子们的孩子们的工作不及格,他们的孩子们就会不及格。这种行为不是通过工作的孩子来传递的

在我看来,这也是有意义的,因为你的默认行为取消等应该是相同的,直到你改变它为一个特定的协程


要回答您的问题,您需要明确说明您希望与SupervisorJob的行为启动协同程序。

我将让代码来说明:

fun main() = runBlocking {
    val scopeSupervisor = SupervisorJob()
    val explicitSupervisor = SupervisorJob()
    val explicitPlainJob = Job()
    val scope = CoroutineScope(Dispatchers.Main + scopeSupervisor)

    scopeSupervisor.printJobClass("scopeSupervisor")
    explicitPlainJob.printJobClass("explicitPlainJob")
    println()
    scope.launch {
        coroutineContext.printJobClass("context 1")
        scopeSupervisor.printChildren("scopeSupervisor")
    }.join()
    scope.launch(explicitSupervisor) {
        coroutineContext.printJobClass("context 2")
        explicitSupervisor.printChildren("explicitSupervisor")
    }.join()
    scope.launch(explicitPlainJob) {
        coroutineContext.printJobClass("context 3")
        explicitPlainJob.printChildren("explicitPlainJob")
    }.join()
}

fun CoroutineContext.printJobClass(msg: String) {
    println("$msg class: ${this[Job]!!.className}")
}

fun Job.printChildren(msg: String) {
    println("$msg children: ${children.map { it.className }.joinToString()}")
}

val Any.className get() = this::class.java.simpleName
这张照片

scopeSupervisor class: SupervisorJobImpl
explicitPlainJob class: JobImpl

context 1 class: StandaloneCoroutine
scopeSupervisor children: StandaloneCoroutine
context 2 class: StandaloneCoroutine
explicitSupervisor children: StandaloneCoroutine
context 3 class: StandaloneCoroutine
explicitPlainJob children: StandaloneCoroutine
解释:

作用域中的作业和显式传入的作业都不会成为与协同例程关联的作业。协同程序作业的类型始终为
StandaloneCoroutine
,它是传入作业的子项

还请注意,传入一个显式的
SupervisorJob
是错误的,它不是作用域作业的子项。如果取消范围中的顶级作业,这将不会传播到您创建的显式
SupervisorJob