StragaSevera
02/17/2025, 2:02 PMcreateChannel2
is working but createChannel1
is not.
private suspend fun createChannel1(): ReceiveChannel<Int> = coroutineScope {
produce {
(0..20).forEach { send(it.also { println("Emitting $it in channel...") }) }
}
}
private fun CoroutineScope.createChannel2(): ReceiveChannel<Int> = produce {
(0..20).forEach { send(it.also { println("Emitting $it in channel...") }) }
}
suspend fun main(args: Array<String>) = coroutineScope {
val channel = createChannel2()
println("Got channel!")
for (i in channel) {
println(i)
}
}
When using the first function, the code outputs Emitting 0 in channel...
and then freezes. Could somebody explain to me why doesn't it work like that? Why do you need to make it an extension function?Dmitry Khalanskiy [JB]
02/17/2025, 2:07 PMCould somebody explain to me why doesn't it work like that?
coroutineScope { ... }
only finishes when all the child coroutines spawned in ...
also finish. By default, produce
creates a channel without a buffer, so after sending the first element, it needs to wait for the element to be consumed before sending another one. Yet because the createChannel1
function hasn't finished yet, no one can consume that element. We have a deadlock: the producer coroutine can't finish because its elements are only consumed after createChannel
, and createChannel1
can't finish because the producer coroutine is still running.
The second function, on the other hand, finishes immediately after creating a producer coroutine. It uses the outer coroutineScope
as the scope in which that coroutine runs.StragaSevera
02/17/2025, 2:09 PMDmitry Khalanskiy [JB]
02/17/2025, 2:12 PMCoroutineScope()
function, but that's only useful in advanced scenarios where you have a thing with some specific lifetime and want to make sure all coroutines launched in that scope finish their work inside that lifetime.
coroutineScope {}
is the simple default scenario where the lifetime of the coroutines is the duration of the coroutineScope
function call.StragaSevera
02/17/2025, 2:13 PMcoroutineScope
by default and scope-passing if we need to launch some long-running operation? Is this rule of thumb correct?Dmitry Khalanskiy [JB]
02/17/2025, 2:14 PMStragaSevera
02/17/2025, 2:14 PM