无法关闭 Kotlin 通道

huangapple go评论51阅读模式
英文:

Unable to close a kotlin channel

问题

我正在尝试理解为什么在调用close后,Kotlin通道没有关闭,在下面是一段基本的代码:

@Test
fun `test channel`() = runBlocking {
    val buffer = Channel<Int>(3)
    val job = launch {
        launch {
            buffer.send(1)
            delay(1000)
            buffer.send(2)
            delay(1000)
            buffer.send(3)
            delay(1000)
            buffer.close()
        }

        launch {
            while (!buffer.isClosedForReceive) {
                println("isClosed " + buffer.isClosedForReceive)
                delay(5000)
            }
        }
    }

    job.join()
}

我有Kotlin协程,第一个协程每秒发送一个整数3次,然后关闭它,而第二个协程则检查通道是否已关闭。

第二个协程永远不会退出,并且一直显示:

isClosed false
isClosed false
isClosed false

有什么想法为什么会这样吗?

英文:

I am trying to understand why a kotlin channel is not closed after I call close on it, below a basic code:

@Test
fun `test channel`() = runBlocking {
    val buffer = Channel&lt;Int&gt;(3)
    val job = launch {
        launch {
            buffer.send(1)
            delay(1000)
            buffer.send(2)
            delay(1000)
            buffer.send(3)
            delay(1000)
            buffer.close()
        }

        launch {
            while (!buffer.isClosedForReceive) {
                println(&quot;isClosed &quot; + buffer.isClosedForReceive)
                delay(5000)
            }
        }
    }

    job.join()
}

I have kotlin coroutines, 1st sends an int every second 3 times and then close it and the 2nd one check if the channel has been closed or not

The 2nd coroutine do never exist, and keep displaying:

isClosed false
isClosed false
isClosed false

Any idea why?

答案1

得分: 1

close()的文档所述,通道在发送方面会立即关闭,但在消耗所有元素后才会在接收方面关闭:

在调用此函数后,isClosedForSend会立即返回true。然而,在ReceiveChannel一侧,只有在所有先前发送的元素都被接收后,isClosedForReceive才会返回true。

您未从通道中消耗任何元素,因此它始终包含等待消耗的元素。这就是为什么它在接收方面永远不会关闭的原因。

英文:

As the documentation for close() says, the channel is immediately closed only for sending, but it is closed for receiving after consuming all its items:

> Immediately after invocation of this function, isClosedForSend starts returning true. However, isClosedForReceive on the side of ReceiveChannel starts returning true only after all previously sent elements are received.

You don't consume items from the channel, so it always contains items that still wait to be consumed. This is why it never closes for receiving.

huangapple
  • 本文由 发表于 2023年8月4日 02:53:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830912.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定