扇出/扇入 - 关闭结果通道

时间:2017-07-31 08:23:19

标签: kotlin channel coroutine kotlinx.coroutines

我正在制作项目,从多个协同例程中消耗并推回到resultChannel。制作人在最后一个项目后关闭其频道。

代码永远不会结束,因为resultChannel永远不会被关闭。如何检测并正确完成迭代,以便hasNext()返回false

val inputData = (0..99).map { "Input$it" }
val threads = 10

val bundleProducer = produce<String>(CommonPool, threads) {
    inputData.forEach { item ->
        send(item)
        println("Producing: $item")
    }

    println("Producing finished")
    close()
}

val resultChannel = Channel<String>(threads)

repeat(threads) {
    launch(CommonPool) {
        bundleProducer.consumeEach {
            println("CONSUMING $it")
            resultChannel.send("Result ($it)")
        }
    }
}

val iterator = object : Iterator<String> {
    val iterator = resultChannel.iterator()
    override fun hasNext() = runBlocking { iterator.hasNext() }
    override fun next() = runBlocking { iterator.next() }
}.asSequence()

println("Starting interation...")

val result = iterator.toList()

println("finish: ${result.size}")

1 个答案:

答案 0 :(得分:4)

您可以运行一个等待消费者完成的协程,然后关闭fill = "x"

首先,重写启动使用者的代码以保存resultChannel

Job

然后在完成所有val jobs = (1..threads).map { launch(CommonPool) { bundleProducer.consumeEach { println("CONSUMING $it") resultChannel.send("Result ($it)") } } } 后运行另一个关闭通道的协程:

Job