为什么具有无限缓冲通道的生产者不会 return 或 return 来自通道的无效数据?
Why the producer with unlimited buffered channel doesn't return or return invalid data from channel?
看看这个采纳了example from official Kotlin documentation:
package com.example
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.runBlocking
fun main(args: Array<String>) = runBlocking {
val producer = produce {
for (x in 1..5) send(x)
}
for (i in producer) {
println(i)
}
println("Done!")
}
如果我 运行 它将打印:
1
2
3
4
5
Done!
如您所见,默认情况下使用无缓冲通道。让我们将其更改为缓冲通道:
package com.example
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.runBlocking
fun main(args: Array<String>) = runBlocking {
val producer = produce(capacity = Channel.UNLIMITED) {
for (x in 1..5) send(x)
}
for (i in producer) {
println(i)
}
println("Done!")
}
如果我运行它几次它会打印:
1
Done!
或
2
Done!
或者只是
Done!
我假设生产者会将数据放入缓冲通道并且 for
循环将从中读取数据直到它可以完成(即,如果通道中存在数据或通道中不存在数据,它将读取关闭)。因此,我认为 for
循环应该从缓冲通道中读取所有数据,即使它已关闭。我说得对吗?
谁能解释一下为什么缓冲通道会导致生产者出现这种奇怪的行为?是错误吗?
P.S.
- kotlin-stdlib v.1.2.21(今天是最后一个版本)
- kotlinx-coroutines-core v.0.22.2(今天是最后一个版本)
Kotlin 团队已确认这是一个错误,并opened an issue针对此问题作出回应。
问题的描述提到它只出现在 produce
构建器中并提供了一个解决方法,基本上是该便利构造的内联代码:
val producer = Channel<Int>(1)
launch(coroutineContext) {
for(i in 1..2) {
producer.send(i)
println("Sent: $i")
}
producer.close()
}
看看这个采纳了example from official Kotlin documentation:
package com.example
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.runBlocking
fun main(args: Array<String>) = runBlocking {
val producer = produce {
for (x in 1..5) send(x)
}
for (i in producer) {
println(i)
}
println("Done!")
}
如果我 运行 它将打印:
1
2
3
4
5
Done!
如您所见,默认情况下使用无缓冲通道。让我们将其更改为缓冲通道:
package com.example
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.runBlocking
fun main(args: Array<String>) = runBlocking {
val producer = produce(capacity = Channel.UNLIMITED) {
for (x in 1..5) send(x)
}
for (i in producer) {
println(i)
}
println("Done!")
}
如果我运行它几次它会打印:
1
Done!
或
2
Done!
或者只是
Done!
我假设生产者会将数据放入缓冲通道并且 for
循环将从中读取数据直到它可以完成(即,如果通道中存在数据或通道中不存在数据,它将读取关闭)。因此,我认为 for
循环应该从缓冲通道中读取所有数据,即使它已关闭。我说得对吗?
谁能解释一下为什么缓冲通道会导致生产者出现这种奇怪的行为?是错误吗?
P.S.
- kotlin-stdlib v.1.2.21(今天是最后一个版本)
- kotlinx-coroutines-core v.0.22.2(今天是最后一个版本)
Kotlin 团队已确认这是一个错误,并opened an issue针对此问题作出回应。
问题的描述提到它只出现在 produce
构建器中并提供了一个解决方法,基本上是该便利构造的内联代码:
val producer = Channel<Int>(1)
launch(coroutineContext) {
for(i in 1..2) {
producer.send(i)
println("Sent: $i")
}
producer.close()
}