是否有一种很好的方法让 channel 在关闭后忽略报价而不引发异常?
目前,由于isClosedForSend
并不是原子的,因此似乎只有try catch才有效。
另外,如果我根本不关闭 channel ,是否有问题?
对于我的特定用例,我使用通道替代Android livedata(因为除了从任何线程发送值和从主线程侦听之外,我不需要任何其他好处)。在这种情况下,我可以通过仅在需要时发送值的生产者来监听通道,而忽略所有其他输入。
理想情况下,我有一个解决方案,其中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个值。
关于第二个问题:这取决于。
通道没有这么大的开销,挂起的协程也没有。但是,泄漏就是泄漏,您知道的。