次のプログラムを実行します。
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 で入手できます。