关闭后忽略对coroutine通道的提议

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关闭后忽略对coroutine通道的提议相关的知识,希望对你有一定的参考价值。

有没有一种好方法让频道在关闭后忽略优惠而不抛出异常?

目前,似乎只有尝试捕获才能起作用,因为isClosedForSend不是原子的。

或者,如果我根本不关闭某个频道,是否会出现问题?对于我的特定用例,我使用渠道作为android liveata的替代品(因为除了从任何线程发送值并从主线程中侦听之外,我不需要任何其他好处)。在这种情况下,我可以通过生产者来监听频道,该生产者只在我想要的时候发送值,并且只是忽略所有其他输入。

理想情况下,我有一个解决方案,ReceiveChannel仍然可以听完,但SendChannel在提供新值时永远不会崩溃。

答案

渠道抛出这个例外by design,作为正确沟通的手段。

如果你绝对必须有这样的东西,你可以使用这种扩展功能:

private suspend fun <E> Channel<E>.sendOrNothing(e: E) {
    try {
        this.send(e)
    }
    catch (closedException: ClosedSendChannelException) {
        println("It's fine")
    }
}

您可以使用以下代码对其进行测试:

val channel = Channel<Int>(capacity = 3)
    launch {

        try {
            for (i in 1..10) {
                channel.sendOrNothing(i)
                delay(50)
                if (i == 5) {
                    channel.close()
                }
            }

            println("Done")
        }
        catch (e: Exception) {
            e.printStackTrace()
        }
        finally {
            println("Finally")
        }
    }

    launch {
        for (c in channel) {
            println(c)
            delay(300)
        }
    }

正如您将注意到的那样,由于频道已关闭,制作人将开始打印“很好”,但消费者仍然可以阅读前5个值。

关于你的第二个问题:这取决于。

频道没有这么大的开销,也没有暂停的协同程序。但是你知道,泄漏是泄漏。

另一答案

我最终将an issue发布到了repo,解决方案是使用BroadcastChannel。你可以通过ReceiveChannel创建一个新的openSubscription,关闭它不会关闭SendChannel

这更准确地反映了RxJava的PublishSubject

以上是关于关闭后忽略对coroutine通道的提议的主要内容,如果未能解决你的问题,请参考以下文章

使用 Kotlin Coroutines 更新我的 TextView 会导致它崩溃:

如何使用提议/答案交换来自两个对等连接的流

C#动态调用webService出现 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。

在应用关闭时单击 Firebase 通知后打开特定的活动/片段

C# 最有用的(自定义)代码片段是啥? [关闭]

快手回应董事长宿华“被带走配合调查”:恶意谣言,已报案;苹果关闭iOS 15.4.1验证通道;Linux 5.18发布|极客头条