JavaFx2或ScalaFx + Akka

Maa*_*mon 21 scala javafx akka javafx-2 scalafx

如何在JavaFX/ScalaFX应用程序中运行Akka actor?

(这是基于第一个答案的问题更新)

解决方案是共享相同的执行上下文吗?是否有基于JavaFx ExecutorService的Actors调度程序?(运行UI操作代码的那个)

这是否意味着一个代理将代表UI并能够操纵它?我的意思是因为如果在UI ExecutorService上有几个actor,建议如下,这是不是意味着在代理(对象是UI)之间共享一个状态?

2个演员可以在不同的执行器服务上进行通信吗?我问这个是因为根据下面的建议,一些代理将在UI Executor服务上,而其他代理不在.

最后,为什么使用akka,它的Executor上下文不同并使用Platform.runLater,可能会对UI的性能产生一些影响.我在同一个应用程序中提出了多个执行程序服务的问题:那是不是很糟糕?

Rüd*_*ehn 22

  • 期货

将scala Futures与单线程工具包(如JavaFX)一起使用的最佳方法是定义一个执行程序,允许您在UI Toolkit的线程上执行future或actors.

Swing也存在同样的问题,它还需要在swing线程上进行更新.Viktor Klang提出了以下解决方案Swing Execution Context.这里是为JavaFX翻译的:

import akka.dispatch.ExecutionContext
import javafx.application.Platform
import java.util.concurrent.Executor

//
object JavaFXExecutionContext {
  implicit val javaFxExecutionContext: ExecutionContext = ExecutionContext.fromExecutor(new Executor {
  def execute(command: Runnable): Unit = Platform.runLater(command)
  })
}
Run Code Online (Sandbox Code Playgroud)

你会像这样使用它:

// import the default ec
import scala.concurrent.ExecutionContext.Implicits.global
// define the JavaFX ec so we can use it explicitly
val fxec = JavaFXExecutionContext.javaFxExecutionContext
future {
  // some asynchronous computation, running on the default
  // ForkJoin ExecutionContext because no ec is passed
  // explicitly
}.map(result => {
  // update JavaFX components from result
  // This will run in the JavaFX thread.
  // Check Platform.isFxApplicationThread() to be sure!
})(fxec)
Run Code Online (Sandbox Code Playgroud)

只要与JavaFX组件交互的步骤都在JavaFX ExecutionContext上运行,期货管道就会非常复杂.

注意:由您决定是否使ForkJoin ec成为默认值并明确传递JavaFX ec,反之亦然.将JavaFX ec设置为默认值以防止错误并标记可以使用ForkJoin ec显式异步运行的部分可能是个好主意.

  • 演员

为了将基于Actor的系统与单线程UI工具包集成,还有一个解决方案.见Swing Actors.你所要做的就是更换

SwingUtilities.invokeLater(command)
Run Code Online (Sandbox Code Playgroud)

Platform.runLater(command)
Run Code Online (Sandbox Code Playgroud)

你很高兴去!

  • 什么时候用哪个

如果你有一个很棒的UI应用程序,并且想要分离一些异步操作(加载文件或进行一些计算),那么基于期货的方法可能更可取.但是请注意不要在默认执行上下文中异步运行的期货中与JavaFX组件进行任何交互(既不读也不写).

如果您有一个基于actor的大型系统并且只想将UI附加到某些部分,那么在JavaFX线程上运行一些actor可能更可取.因人而异.


Knu*_*daa 6

在JavaFX中使用多个线程时,您需要考虑以下几点:

  • 任何最终触及场景图的代码(例如,通过更新绑定到控件的数据)都必须包含在内Platform.runLater.如果您在JavaFX中使用内置的多线程API(即TaskService),这将自动完成,但如果您使用任何其他多线程实用程序,则必须自己完成.

  • 您的多线程实用程序(即Akka)必须(我认为)以某种方式被告知为JavaFX事件线程留出一些空间.如果查看服务源,您会发现在配置执行程序时需要非常小心.我不确定这个的细节,但是当我尝试在FutureJavaFX中使用Scala时,我在使用默认值时在UI中观察到一些无响应,ExecutionContext当我使用基于Service实现的自定义时,消失了.

ScalaFX(或据我所知的任何其他工具包)都没有支持使用Scala Futures或Akka以一种让你忘记上述两点的方式,但是看一下它肯定会很有趣.


muc*_*aho 6

是关于可以在Swing或JavaFX线程上运行的akka​​ actor的要点.根据Rüdiger的回答,它是Victor Klang的Swing Actors的一个方便的,可复制的扩展.