启动协程时,它可能只创建一个onStop
并从中调用launch {}-CoroutineScope
,
或从doSomething_2()
派生该类,并使用要启动的类{}。 -CoroutineScope
。
这两者之间是否有区别,哪种方法更可取?
doSomething_1()
答案 0 :(得分:3)
这两者之间是否有区别,哪种方法更可取?
是的,有一个根本的区别,那就是一个正确而另一个错误。它与结构化并发有关:如果您的AClass
是“工作单元”的根对象,无论它是什么,并且负责其生命周期(或观察者),那么它也应该是根您将在其中启动协程的范围。生命周期结束时,AClass
应该通过在自身上调用cancel
来取消根作用域,从而将该事件传播到协程子系统。 CoroutineScope.cancel
是扩展功能。
我接受了您的代码并进行了以下修复:
CoroutineScope.coroutineContext
里面必须有Job()
,所以我添加了它。我删除了调度程序,因为它与该故事无关,并且Main
调度程序用于GUI,而我们正在运行一个简单的测试。
我删除了您的dispose()
函数,我们有cancel()
开箱即用。
我删除了theJob1
和theJob2
字段,因为一旦正确开始使用结构化并发,它们就毫无用处。
我还添加了一些代码,使我们能够观察到这种行为:
在每个协程中添加一个delay
和一个println
,以查看完成的时间。
添加了main
函数以对其进行测试。该功能永远在最后一行阻塞,以便我们可以查看启动的协程将执行的操作。
这是代码:
import kotlinx.coroutines.*
import java.lang.Thread.currentThread
import kotlin.coroutines.CoroutineContext
fun main() {
val a = AClass()
a.doSomething_1()
a.doSomething_2()
a.cancel()
currentThread().join()
}
class AClass : CoroutineScope {
override val coroutineContext: CoroutineContext = Job()
fun doSomething_1() {
launch(Dispatchers.IO) {
try {
delay(10_000)
} finally {
println("theJob1 completing")
}
}
}
fun doSomething_2() {
CoroutineScope(Dispatchers.IO).launch {
try {
delay(10_000)
} finally {
println("theJob2 completing")
}
}
}
}
运行它时,您只会看到theJob1
完成而theJob2
运行了整整10秒钟,而没有遵循cancel
信号。
这是因为构造CoroutineScope(Dispatchers.IO)
会创建一个独立的作用域,而不是成为AClass
范围的子级,从而破坏了协程的层次结构。
从理论上讲,您仍然可以使用显式的CoroutineScope
构造函数来保持层次结构,但随后您将发现显然不是首选的方法:
CoroutineScope(coroutineContext + Dispatchers.IO).launch {
这等同于
launch(Dispatchers.IO) {
答案 1 :(得分:1)
这两个协程将在相同的上下文中启动。您可以通过在两个位置同时打印协程上下文来查看此内容:
launch(Dispatchers.IO) {
println("doSomething_1 context: ${coroutineContext}")
}
CoroutineScope(Dispatchers.IO).launch {
println("doSomething_2 context: ${coroutineContext}")
}
这将打印如下内容:
doSomething_1 context: [StandaloneCoroutine{Active}@7b8cce78, Dispatchers.IO]
doSomething_2 context: [StandaloneCoroutine{Active}@3c938006, Dispatchers.IO]
我还没有看到CoroutineScope
在内部协程代码之外经常实现的情况。在这种情况下,您应该偏重于继承而不是继承,尤其是因为CoroutineContext
可以使用+
运算符构成其核心。例如,当您launch
使用新的协程时,现有上下文将与您提供的新上下文简单组合。
进一步阅读: