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

JP

03/20/2020, 2:29 PM
I’d like to ask if I understood this correct: https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html#cancellation-is-cooperative
Copy code
import 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:
Copy code
[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?
a

araqnid

03/20/2020, 7:30 PM
right, if there are no suspension points and you don’t check for cancellation any other way (e.g.
CoroutineScope.isActive
), then the routine just keeps going.
👍 1
Yes, aiui every time a coroutine (that uses the core dispatchers) resumes it will check for cancellation
j

JP

03/21/2020, 2:43 AM
Let me slightly rephrase the P.S. question: In the documentation it is stated:
All the suspending functions in 
kotlinx.coroutines
 are cancellable.
If I define a new suspending function that doesn’t use other suspending functions in
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.
a

araqnid

03/21/2020, 1:34 PM
as long as you’ve started the coroutine off with one of the launchers from kotlinx.coroutines (launch, async, produce, flow etc) then they will put a wrapped dispatcher into the coroutine context that will automatically check for cancellation. That will naturally propagate as you call suspend functions unless you go to some effort to stop it. It’s only if you start calling
.startCoroutine
or its friends from stdlib directly that you’ll lose the cancellation facilities.
👍 2
u

uli

03/21/2020, 7:18 PM
if you define a suspending function that does not call any other suspending functions you do not have a suspension point and are not cancelable
j

Jérôme Gully

03/22/2020, 2:46 PM
Hi, you will find a fresh good article write by Florina Muntenescu about cancellation in coroutines: https://medium.com/androiddevelopers/cancellation-in-coroutines-aa6b90163629 Hop it will help to better handle it !
3 Views