【发布时间】:2020-10-20 17:42:56
【问题描述】:
所以我有一个具有生命周期的类,其中包含一个 start() 和一个 stop() 函数来启动和停止生命周期。现在在start() 函数中我必须启动一个协程,在stop() 我必须取消它(start() 中的协程无限运行直到它被取消,有点像监听消息的套接字)。
因为我想要一个很好的语法来处理协程,所以我希望这个类实现CoroutineScope。问题是start() 和stop() 可以被多次调用。
我的问题是这个实现是否有效并且不包含任何错误。目的是制作一个可重复使用的CoroutineScope。
class ReusableCoroutines() : CoroutineScope {
private var job = Job()
override val coroutineContext: CoroutineContext
get() = job
fun start() {
job = Job()
launch {
println("Started and running!")
while(true) {
}
}
}
fun stop() {
job.cancel()
println("Stoped")
}
}
【问题讨论】:
-
我可以看到这里发生的事情是你的工作开始了两次,第一个永远不会被取消,或者访问你的 coroutineContext 的东西以一个过时的
Job结束。另外(只是为了确定)- 仅仅因为您将cancel发送到作业并不意味着它实际上已停止,您可以将您的while(true)循环更改为while(isActive)以确保它在取消时停止。 -
你应该让
job可以为空并且如果它被启动两次就会失败(正如@Joozd 提到的),如果在范围停止时访问coroutineContext也会失败(get() = checkNotNull(job) { "scope not started" })。您还需要考虑是否可以同时调用start和/或stop,因为这可能导致竞争条件。此外,您在这里打破了结构化并发:kotlinlang.org/docs/reference/coroutines/basics.html -> 结构化并发 -
放弃制作可重用
CoroutineScope的希望。如果您有一个生命周期可以停止和启动的类,请使其包含一个具有单一生命周期的类,该生命周期只启动和停止一次。
标签: kotlin kotlin-coroutines coroutine