Search code examples
kotlinkotlinx.coroutines

Kotlin: receiving elements in different coroutine is not working properly


I've below kotlin coroutine code.

    import kotlinx.coroutines.*
    import kotlinx.coroutines.channels.*

    fun main() = runBlocking <Unit> {
        val channel = Channel<Int>(4)
        val sender = launch (coroutineContext) {
            repeat(10) {
                println("sending $it")
                channel.send(it)
                delay(100)
            }
        }

        delay(1000)

        //launch {  for (y in channel) println("receiving $y") }

        for (y in channel) println("receiving $y")
    }

It works fine. If I put the logic to receive elements from channel into another coroutine(i.e., put for inside launch as in commented code), then it gets struck at below output(i.e., I'm expecting sending and receiving till 10 but it gets stuck at receiving 3).

    sending 0
    sending 1
    sending 2
    sending 3
    sending 4
    receiving 0
    receiving 1
    receiving 2
    receiving 3

How to receive elements in another coroutine without any glitches?

I'm using version compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1")


Solution

  • The reason is that your channel is not closed, so your for-each loop may never end. If you close your channel after the repeat block, you the code will be finished gracefully:

    import kotlinx.coroutines.* import kotlinx.coroutines.channels.*

    fun main() = runBlocking <Unit> {
        val channel = Channel<Int>(4)
        val sender = launch (coroutineContext) {
            repeat(10) {
                println("sending $it")
                channel.send(it)
                delay(100)
            }
            channel.close()
        }
    
        delay(1000)
    
        launch {  for (y in channel) println("receiving $y") }
    
    }