丢弃 Scala actor 中除最后一条消息之外的所有消息

发布于 2024-12-08 08:56:36 字数 575 浏览 5 评论 0原文

我有一个 SwingWorker 演员,它根据发送的参数对象计算要显示的绘图;然后在 EDT 线程上绘制绘图。一些 GUI 元素可以调整该图的参数。当它们发生变化时,我生成一个新的参数对象并将其发送给工作人员。

到目前为止这有效。

现在,当移动滑块时,会创建许多事件并在工作人员的邮箱中排队。但我只需要计算最后一组参数的绘图。有没有办法删除收件箱中的所有邮件?保留最后一个并仅处理它?

目前代码如下所示

val worker = new SwingWorker {
  def act() {
    while (true) {
      receive {
        case params: ExperimentParameters => {
          //somehow expensive
          val result = RunExperiments.generateExperimentData(params)

          Swing.onEDT{ GuiElement.redrawWith(result) }
        }
      }
    }
  }
}

I have a SwingWorker actor which computes a plot for display from a parameters object it gets send; then draws the plot on the EDT thread. Some GUI elements can tweak parameters for this plot. When they change I generate a new parameter object and send it to the worker.

This works so far.

Now when moving a slider many events are created and queue up in the worker's mailbox. But I only need to compute the plot for the very last set of parameters. Is there a way to drop all messages from the inbox; keep the last one and process only that?

Currently the code looks like this

val worker = new SwingWorker {
  def act() {
    while (true) {
      receive {
        case params: ExperimentParameters => {
          //somehow expensive
          val result = RunExperiments.generateExperimentData(params)

          Swing.onEDT{ GuiElement.redrawWith(result) }
        }
      }
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

玩心态 2024-12-15 08:56:36

同时我找到了解决方案。您可以检查演员的邮箱大小,如果不为0则跳过该消息。

val worker = new SwingWorker {
  def act() {
    while (true) {
      receive {
        case params: ExperimentParameters => {
          if( mailboxSize == 0) {
            //somehow expensive
            val result = RunExperiments.generateExperimentData(params)
            Swing.onEDT{ GuiElement.redrawWith(result) }
          }
        }
      }
    }
  }
}

Meanwhile I have found a solution. You can check the mailbox size of the actor and simply skip the message if it is not 0.

val worker = new SwingWorker {
  def act() {
    while (true) {
      receive {
        case params: ExperimentParameters => {
          if( mailboxSize == 0) {
            //somehow expensive
            val result = RunExperiments.generateExperimentData(params)
            Swing.onEDT{ GuiElement.redrawWith(result) }
          }
        }
      }
    }
  }
}
滥情空心 2024-12-15 08:56:36

记住最后一个事件而不处理它,有一个很短的超时,当你得到超时时处理最后一个事件

可能看起来像(未经测试)

while(true) {
  var lastReceived : Option[ExperimentParameters] = None
  receive {case params : ExperimentParameters => lastReceived = Some(params)}
  while (!lastReceived.isEmpty) {
    receiveWithin(0) {
      case params: ExperimentParameters => lastReceived = Some(params)
      case TIMEOUT => do your job with lastReceived.get;
    }
  }
}

Remember the last event without processing it, have a very short timeout, process the last event when you get the timeout

could look like (not tested)

while(true) {
  var lastReceived : Option[ExperimentParameters] = None
  receive {case params : ExperimentParameters => lastReceived = Some(params)}
  while (!lastReceived.isEmpty) {
    receiveWithin(0) {
      case params: ExperimentParameters => lastReceived = Some(params)
      case TIMEOUT => do your job with lastReceived.get;
    }
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文