JP
03/20/2020, 2:29 PMimport kotlinx.coroutines.*
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (i < 5) { // computation loop, just wastes CPU
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: 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.")
}
The output is:
[DefaultDispatcher-worker-1 @coroutine#2] job: I'm sleeping 0 ...
[DefaultDispatcher-worker-1 @coroutine#2] job: I'm sleeping 1 ...
[DefaultDispatcher-worker-1 @coroutine#2] job: I'm sleeping 2 ...
[main @coroutine#1] main: I'm tired of waiting!
[DefaultDispatcher-worker-1 @coroutine#2] job: I'm sleeping 3 ...
[DefaultDispatcher-worker-1 @coroutine#2] job: I'm sleeping 4 ...
[main @coroutine#1] main: Now I can quit.
From my understanding, the job
did not get cancelled despite the job.cancelAndJoin()
call, because there is no suspending functions (e.g. delay
) which are cancellable (checks for cancellation cooperatively). Therefore the job completes after five iterations, then the job.join()
returns, and then at last “main: Now I can quit.” is printed. Is this correct?
P.S. Does “every” suspending function always check for cancellation?araqnid
03/20/2020, 7:30 PMCoroutineScope.isActive
), then the routine just keeps going.JP
03/21/2020, 2:43 AMAll the suspending functions inIf I define a new suspending function that doesn’t use other suspending functions inare cancellable.kotlinx.coroutines
kotlinx.coroutines
, is it still implicitly cancellable? Or do I have to insert the code for example, checking with CoroutineScope.isActive
? My guess was the latter.araqnid
03/21/2020, 1:34 PM.startCoroutine
or its friends from stdlib directly that you’ll lose the cancellation facilities.uli
03/21/2020, 7:18 PMJérôme Gully
03/22/2020, 2:46 PM