关闭集合通道不会解锁已经阻塞的发送功能

问题描述 投票:0回答:1

首先创建一个capacity=0的集合通道。然后在串联阻塞调用中调用该通道的 send() 函数。

然后调用通道的close()函数。 Channel.send() 将无限期地阻塞,不会抛出任何异常。

我知道我可以通过调用channel.cancel()来取消send()函数,但是为什么不关闭工作?

这是测试代码:

    @Test
    fun testCloseRendezvousChannel(): Unit = runBlocking {
        // Make sure capacity is zero
        val channel = Channel<Int>(0)

        launch {
            try {
                println("send begin")
                channel.send(0)
            } catch (e: Exception) {
                println("send caught exception: $e")
            } finally {
                println("send over")
            }
        }

        delay(100L)
        channel.close() // do not call channel.cancel()
        println("test over")
        delay(1000L)
    }

输出为:

send begin
test over

未得到预期输出

send over

kotlin-coroutines channel
1个回答
0
投票

Channel.close()
旨在表示将不再有元素发送到此
Channel
,但已发送但未收到的元素仍然可用。对于集合通道,这意味着即使通道随后关闭以进行发送,
send
也会暂停。

来自 SendChannel.close 上的

文档

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

同时cancel不仅关闭

Channel
,还清除元素:

此函数关闭通道并从中删除所有缓冲的发送元素。

© www.soinside.com 2019 - 2024. All rights reserved.