0

次のプログラムを実行します。

package example

import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.selects.select

@InternalCoroutinesApi
fun main() {
    runBlocking {
        val chan = Channel<Unit>()
        chan.close()
        select<Unit> {
            println("Register onReceiveOrClosed.")
            chan.onReceiveOrClosed {
                println("Selected value $it.")
            }
        }
        println("Done.")
    }
}

実行すると、次の出力が得られます。

Register onReceiveOrClosed.
Selected value Closed(null).
Selected value Closed(null).
Exception in thread "main" java.lang.IllegalStateException: Already resumed
    at kotlinx.coroutines.selects.SelectBuilderImpl.resumeWith(Select.kt:458)
    at kotlinx.coroutines.selects.SelectBuilderImpl.handleBuilderException(Select.kt:309)
    at example.ExampleKt$main$1.invokeSuspend(example.kt:28)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:270)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:79)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at example.ExampleKt.main(example.kt:10)
    at example.ExampleKt.main(example.kt)

1 行だけがSelected value Closed(null)表示され、例外は表示されないと予想されます (ただし、指定されたブロックが 2 回実行されることを考えると、もちろん例外は理にかなっていますonReceiveOrClosed)。

私の理解はonReceiveOrClosed間違っていますか、それともバグonReceiveOrClosedですか?

Kotlin 1.3.50 とkotlinx-coroutines-core:1.3.1. 完全な例は、https ://github.com/frececroka/kotlin-select-onreceiveorclosed で入手できます。

4

1 に答える 1