Execution stucks on Channel.send

67 Views Asked by At

I have a suspend kotlin function which should get the first value from a flow and return it. However it stucks on ch.send(st)

    private suspend fun readSensorTemperature(): Double {
        val ch = Channel<Double>()

        val job = coroutineScope {
            launch {
                myFlow.collect { st ->
                    ch.send(st)
                }
            }
        }

        val res = ch.receive()
        job.cancel()

        return res
    }

Why my code does not work?

2

There are 2 best solutions below

2
On

Do you really need to do this? A simpler way to get the first value from a flow is with myFlow.first().

The reason your current code is suspending indefinitely is that the call to coroutineScope will suspend until all of its child coroutines have completed.

Because you call collect inside the coroutineScope, the coroutineScope cannot complete until the flow collection has completed. That means your code will never reach the calls to receive and cancel which would allow the flow collection to proceed and then be terminated.

A solution would be to move the receive and cancel calls inside the coroutineScope.

2
On

Such code seems to be working for me

suspend fun readSensorTemperature(): Double {
    var res: Double = -1.0

    val job = coroutineScope {
        launch {
            sensorTemperature.collect { st ->
                Log.d("ST", "Sensor temperature: $st")
                res = st
                cancel()
            }
        }
    }

    job.join()
    return res
}