简体   繁体   English

JavaFx2或ScalaFx + Akka

[英]JavaFx2 or ScalaFx + Akka

How to run Akka actors in a JavaFX/ScalaFX Application ? 如何在JavaFX / ScalaFX应用程序中运行Akka actor?

(This is an update of question based on the first answers) (这是基于第一个答案的问题更新)

Is the solution to share the same execution context? 解决方案是共享相同的执行上下文吗? Meaning having the Actors dispatchers based on the JavaFx ExecutorService ? 是否有基于JavaFx ExecutorService的Actors调度程序? (The one with which on which it runs UI manipulation code) (运行UI操作代码的那个)

Does that mean one agent would represent the UI and be able to manipulate it ? 这是否意味着一个代理将代表UI并能够操纵它? I mean because suggested below if a couple of actor are on the UI ExecutorService, doesn't that mean share a state between agent (the object being the UI)? 我的意思是因为如果在UI ExecutorService上有几个actor,建议如下,这是不是意味着在代理(对象是UI)之间共享一个状态?

Can 2 actors communicate while being on different executor services? 2个演员可以在不同的执行器服务上进行通信吗? I'm asking this because from what is suggested below, some agent would be on the UI Executor Service while other not. 我问这个是因为根据下面的建议,一些代理将在UI Executor服务上,而其他代理不在。

Finally, why using akka as is, with its on Executor context different and using Platform.runLater, might have some consequence on the performance of the UI. 最后,为什么使用akka,它的Executor上下文不同并使用Platform.runLater,可能会对UI的性能产生一些影响。 I this pose the question of multiple executor service on the same application: Is that bad? 我在同一个应用程序中提出了多个执行程序服务的问题:那是不是很糟糕?

  • Futures 期货

The best way to use scala Futures together with a single-threaded toolkit such as JavaFX would be to define an executor that allows you to execute futures or actors on the thread of the UI Toolkit. 将scala Futures与单线程工具包(如JavaFX)一起使用的最佳方法是定义一个执行程序,允许您在UI Toolkit的线程上执行future或actors。

The same problem exists for Swing, which also requires updates to happen on the swing thread. Swing也存在同样的问题,它还需要在swing线程上进行更新。 Viktor Klang came up with the following solution Swing Execution Context . Viktor Klang提出了以下解决方案Swing Execution Context Here it is translated for JavaFX: 这里是为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)
  })
}

You would use it like this: 你会像这样使用它:

// 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)

The pipeline of futures can be very complex, as long as the step(s) that interact with JavaFX components are all running on the JavaFX ExecutionContext. 只要与JavaFX组件交互的步骤都在JavaFX ExecutionContext上运行,期货管道就会非常复杂。

Note: it is up to you whether you make the ForkJoin ec the default and pass the JavaFX ec explicitly or vice versa. 注意:您是否将ForkJoin ec设为默认值并明确传递JavaFX ec,反之亦然。 It might be a good idea to make the JavaFX ec the default to prevent errors and mark the parts that can run asynchronously explicitly with the ForkJoin ec. 将JavaFX ec设置为默认值以防止错误并标记可以使用ForkJoin ec显式异步运行的部分可能是个好主意。

  • Actors 演员

For integrating an Actor based system with a single-threaded UI toolkit there is also a solution. 为了将基于Actor的系统与单线程UI工具包集成,还有一个解决方案。 See Swing Actors . Swing Actors All you have to do is to replace the 你所要做的就是更换

SwingUtilities.invokeLater(command)

with

Platform.runLater(command)

and you're good to go! 你很高兴去!

  • When to use which 什么时候用哪个

If you have a big UI application and just want to spin off some asynchronous operations (loading a file or doing some computation), the futures-based approach is probably preferable. 如果你有一个很棒的UI应用程序,并且想要分离一些异步操作(加载文件或进行一些计算),那么基于期货的方法可能更可取。 But be careful not to do any interaction (neither read nor write) with JavaFX components in the futures that run asynchronously on the default execution context. 但是请注意不要在默认执行上下文中异步运行的期货中与JavaFX组件进行任何交互(既不读也不写)。

If you have a large actor based system and just want to attach an UI to some parts, having a few actors that run on the JavaFX thread is probably preferable. 如果您有一个基于actor的大型系统并且只想将UI附加到某些部分,那么在JavaFX线程上运行一些actor可能更可取。 YMMV. 因人而异。

There are a couple of things you need to consider when using multiple threads in JavaFX: 在JavaFX中使用多个线程时,您需要考虑以下几点:

  • Any code that ends up touching the scene graph (eg by updating data that is bound to controls) must be wrapped in Platform.runLater . 最终触及场景图的任何代码(例如,通过更新绑定到控件的数据)必须包含在Platform.runLater If you use the built-in multi-threading API in JavaFX (ie Task and Service ) this will be done automatically, but if you use any other multi-threading utility you must do it yourself. 如果您使用JavaFX中的内置多线程API(即TaskService ),这将自动完成,但如果您使用任何其他多线程实用程序,则必须自己完成。

  • Your multi-threading utility (ie Akka) must (I think) somehow be told to leave some room for the JavaFX event thread. 您的多线程实用程序(即Akka)必须(我认为)以某种方式被告知为JavaFX事件线程留出一些空间。 If you look at the source for Service you see that they take quite some care when configuring the executor. 如果查看服务源,您会发现在配置执行程序时需要非常小心。 I'm not sure about the details of this, but when I experimented with using Scala's Future s with JavaFX, I observed some unresponsiveness in the UI when using the default ExecutionContext , that disappeared when I used a custom one based on the Service implementation. 我不确定这个细节,但是当我尝试使用Scala的Future和JavaFX时,我在使用默认的ExecutionContext时在UI中发现了一些无响应,当我使用基于Service实现的自定义时,它就消失了。

There is no support in ScalaFX (or any other toolkit as far as I know) for working with either Scala Futures or Akka in a way that lets you forget about the two points above, but it would surely be interesting to look into. ScalaFX(或据我所知的任何其他工具包)都没有支持使用Scala Futures或Akka以一种让你忘记上述两点的方式,但是看一下它肯定会很有趣。

Here is the gist about akka actors that can be run on the Swing or JavaFX thread. 是关于可以在Swing或JavaFX线程上运行的akka​​ actor的要点。 It is a convenient, copy-pastable extension of Victor Klang's Swing Actors based on Rüdiger's answer . 根据Rüdiger的回答 ,它是Victor Klang的Swing Actors的一个方便的,可复制的扩展。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM