【问题标题】:How can I get a non-blocking infinite loop in a Kotlin Actor?如何在 Kotlin Actor 中获得非阻塞无限循环?
【发布时间】:2020-10-29 16:01:14
【问题描述】:

我想使用 Kotlin 演员消耗一些流数据
我想把我的消费者放在一个演员里面,而它在无限循环中轮询while(true)。然后,当我决定时,我会发送一条消息来阻止消费者。

目前我有这个:

while(true) {
     for (message in channel){    <--- blocked in here, waiting
            when(message) {
                is MessageStop -> consumer.close()
                else -> {}
        }
    }

    consumer.poll()
}

问题
这样做的问题是它只在我向参与者发送消息时运行,所以我的消费者不会在其余时间轮询,因为通道阻塞等待接收下一条消息

还有其他选择吗?有同样问题的人吗?或者类似于演员但没有被 Kotlin 中的频道阻止的东西?

【问题讨论】:

  • 可以kotlin flow 做你想做的事吗?
  • 出于好奇...这里的consumer 是什么?这一切都包含在actor-call 中吗?和/或channel 是如何创建的?

标签: kotlin kotlin-coroutines


【解决方案1】:

由于频道只是一个频道 (https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-channel/index.html),您可以先检查频道是否为空,如果是则开始轮询。否则处理消息。

例如

while(true) {

    while (channel.isNotEmpty()) {
        val message = channel.receive()
        when(message) {
            is MessageStop -> consumer.close()
            else -> {}
        }
     }

    consumer.poll()
}

【讨论】:

  • for (message in channel) 更简单
【解决方案2】:

最后我将 AKKA 与 Kotlin 一起使用,我发现这种方式更容易

【讨论】:

  • 这并不能真正回答你的问题......如果这应该回答“有没有其他选择”,那么很高兴看到代码现在的样子......也许这也有助于了解您要完成的工作,也可能会导致您陈述的问题的实际解决方案...
  • 有道理,抱歉。我接受了正确的答案
【解决方案3】:

你应该使用postDelayed(),例如:

final Runnable r = new Runnable() {
    public void run() {
        // your code here
        handler.postDelayed(this, 1000)
    }
}

您可以将1000 更改为您想要的毫秒延迟。此外,我强烈建议将您的代码放在线程中(如果您还没有)以防止 ANR(应用程序无响应)

【讨论】:

    猜你喜欢
    • 2018-03-27
    • 2022-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多