hannesstruss
04/25/2018, 8:11 PMisActive
works:
fun main(args: Array<String>) = runBlocking {
val job = Job()
val pool = newFixedThreadPoolContext(2, "Cool")
repeat(2) {
launch(pool, parent = job) {
startLoop()
}
}
delay(1000)
println("Canceling")
job.cancel()
delay(1000)
println("End")
Unit
}
suspend fun startLoop() {
while (isActive) {
println("I'm active: ${isActive} in ${Thread.currentThread().name}, my job is cancelled: ${coroutineContext[Job]?.isCancelled}")
Thread.sleep(500)
}
}
calling job.cancel()
will not terminate the loops. The complete output is:
I'm active: true in Cool-1, my job is cancelled: false
I'm active: true in Cool-2, my job is cancelled: false
I'm active: true in Cool-1, my job is cancelled: false
I'm active: true in Cool-2, my job is cancelled: false
I'm active: true in Cool-2, my job is cancelled: false
I'm active: true in Cool-1, my job is cancelled: false
Canceling
I'm active: true in Cool-1, my job is cancelled: true
I'm active: true in Cool-2, my job is cancelled: true
I'm active: true in Cool-1, my job is cancelled: true
I'm active: true in Cool-2, my job is cancelled: true
End
In my real life situation, instead of Thread.sleep
, the coroutine is waiting to read from a blocking queue (poll with timeout). If I use delay(500)
instead of sleeping, the coroutines are cancelled properly. Does a Coroutine have to suspend in order for isActive to change?Marek Defeciński
04/25/2018, 8:28 PMhannesstruss
04/25/2018, 8:29 PMsuspend
fun it resolves to `NonCancellable`: https://github.com/Kotlin/kotlinx.coroutines/blob/master/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/NonCancellable.kt#L36Marek Defeciński
04/25/2018, 8:31 PMhannesstruss
04/25/2018, 8:31 PMMarek Defeciński
04/25/2018, 8:31 PMhannesstruss
04/25/2018, 8:32 PMimport kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.NonCancellable
import kotlinx.coroutines.experimental.NonCancellable.isActive
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.newFixedThreadPoolContext
import kotlinx.coroutines.experimental.runBlocking
import kotlin.coroutines.experimental.coroutineContext
Marek Defeciński
04/25/2018, 8:33 PMhannesstruss
04/25/2018, 8:34 PM1.2.40
suspend fun
into the launch
call, it also works – because I'm accessing isActive
and coroutineContext
from the CoroutineScope
, which resolve to the actual values I needMarek Defeciński
04/25/2018, 8:36 PMpetersommerhoff
04/25/2018, 8:38 PMwhile (coroutineContext[Job]!!.isActive) { ... }
works for me, you don't want to use NonCancellable.isActive
runBlocking<Unit> { ... }
to avoid the awkward return value at the endhannesstruss
04/25/2018, 8:41 PMisActive
outside of CoroutineScope
?