https://kotlinlang.org logo
#coroutines
Title
# coroutines
h

hannesstruss

04/25/2018, 8:11 PM
I have a basic question about how
isActive
works:
Copy code
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:
Copy code
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?
m

Marek Defeciński

04/25/2018, 8:28 PM
may I ask to what isActive resolves?
and coroutineContext ?
so yeah, that's why it's true.
m

Marek Defeciński

04/25/2018, 8:31 PM
and the coroutineContext is ?
m

Marek Defeciński

04/25/2018, 8:31 PM
I wanted to compile myself but is not resolving for me
h

hannesstruss

04/25/2018, 8:32 PM
Copy code
import 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
that's the imports
m

Marek Defeciński

04/25/2018, 8:33 PM
thanks for me that last is not visible
I have 1.2.10
in gradle
h

hannesstruss

04/25/2018, 8:34 PM
I'm on
1.2.40
When I inline the
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 need
m

Marek Defeciński

04/25/2018, 8:36 PM
kotlinx-coroutines-core : 0.22.5 fixes that
I was on 0.22
p

petersommerhoff

04/25/2018, 8:38 PM
Using
while (coroutineContext[Job]!!.isActive) { ... }
works for me, you don't want to use
NonCancellable.isActive
That's just always true
BTW you can also use
runBlocking<Unit> { ... }
to avoid the awkward return value at the end
🙌 1
h

hannesstruss

04/25/2018, 8:41 PM
Yeah, that works, thanks! Is there no global convenience val for
isActive
outside of
CoroutineScope
?
2 Views