Ji Sungbin
Ji Sungbin

Reputation: 1321

Coroutine canceled when the inner flow is collected

In this code, it seems to be canceled when the coroutine encounters a flow collected.

fun main() = runBlocking {
    println("Hi, world!")
    CoroutineScope(Dispatchers.Default).launch {
        innerSuspend()
        println("Bye, world!")
    }.join()
    println("task ended.")
}

suspend fun innerSuspend() {
    println("run: innerSuspend")
    innerFlow().collect {
        println("innerCallback : $it")
    }
}

suspend fun innerFlow() = callbackFlow {
    trySend("U r world?")
    awaitClose { close() }
}

I expected the result of above code to look something like this:

Hi, world!
run: innerSuspend
innerCallback : U r world?
Bye, world!
task ended.

But, contrary to expectations, Bye, world! It is not displayed.

Hi, world!
run: innerSuspend
innerCallback : U r world?

Why is this happening and how can I fix it?

Upvotes: 2

Views: 459

Answers (1)

Tenfour04
Tenfour04

Reputation: 93834

Your coroutine is not cancelled. It is still suspended, waiting for the next item from your Flow. You designed a Flow that never closes, so calling collect() on it will suspend forever.

You put the close() call inside awaitClose { }, as if you only want it to be closed after it is already closed, which doesn't make sense. You should just put close().

suspend fun innerFlow() = callbackFlow {
    trySend("U r world?")
    close()
}

Upvotes: 2

Related Questions