【发布时间】:2020-09-23 20:48:00
【问题描述】:
我想取消挂起功能,但无法访问 isActive。这是自动处理的吗?
suspend fun coolFunction() {
while (isActive) {
/* Do cool stuff */
}
}
【问题讨论】:
标签: kotlin
我想取消挂起功能,但无法访问 isActive。这是自动处理的吗?
suspend fun coolFunction() {
while (isActive) {
/* Do cool stuff */
}
}
【问题讨论】:
标签: kotlin
配合取消,可以定期挂起,最简单的方法是调用yield()
suspend fun coolFunction() {
while (true) {
yield()
/* Do cool stuff */
}
}
您还可以通过选中CoroutineScope.isActive 来支持取消。但是挂起函数本身并不能直接访问调用它的 CoroutineScope。您将不得不使用类似coroutineContext[Job]!!.isActive 的东西,这很笨拙。当您直接使用 launch 之类的东西而不是可以从任何范围调用的 suspend 函数来编写协程时,isActive 会更有用。
【讨论】:
您可以取消正在运行暂停功能的作业或协程范围,以便暂停功能将取消。
private suspend fun CoroutineScope.cancelComputation() {
println("cancelComputation()")
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
// WARNING ? isActive is an extension property that is available inside
// the code of coroutine via CoroutineScope object.
while (isActive) { // cancellable computation loop
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion println("main: Now I can quit.")
/*
Prints:
cancelComputation()
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
main: I'm tired of waiting!
*/
}
【讨论】:
flowafter coroutines。跨度>
delay 这样的内置函数会在其协程被取消时抛出取消异常。那么该函数如何知道它何时被取消呢?这基本上就是我想知道的。 flow 并不适用,我不认为。我的函数执行了一个可能需要长时间运行的过程,然后返回一个值。
Closeable.use,这样如果取消它会清理资源。