簡體   English   中英

JavaFx2或ScalaFx + Akka

[英]JavaFx2 or ScalaFx + Akka

如何在JavaFX / ScalaFX應用程序中運行Akka actor?

(這是基於第一個答案的問題更新)

解決方案是共享相同的執行上下文嗎? 是否有基於JavaFx ExecutorService的Actors調度程序? (運行UI操作代碼的那個)

這是否意味着一個代理將代表UI並能夠操縱它? 我的意思是因為如果在UI ExecutorService上有幾個actor,建議如下,這是不是意味着在代理(對象是UI)之間共享一個狀態?

2個演員可以在不同的執行器服務上進行通信嗎? 我問這個是因為根據下面的建議,一些代理將在UI Executor服務上,而其他代理不在。

最后,為什么使用akka,它的Executor上下文不同並使用Platform.runLater,可能會對UI的性能產生一些影響。 我在同一個應用程序中提出了多個執行程序服務的問題:那是不是很糟糕?

  • 期貨

將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)
  })
}

你會像這樣使用它:

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

只要與JavaFX組件交互的步驟都在JavaFX ExecutionContext上運行,期貨管道就會非常復雜。

注意:您是否將ForkJoin ec設為默認值並明確傳遞JavaFX ec,反之亦然。 將JavaFX ec設置為默認值以防止錯誤並標記可以使用ForkJoin ec顯式異步運行的部分可能是個好主意。

  • 演員

為了將基於Actor的系統與單線程UI工具包集成,還有一個解決方案。 Swing Actors 你所要做的就是更換

SwingUtilities.invokeLater(command)

Platform.runLater(command)

你很高興去!

  • 什么時候用哪個

如果你有一個很棒的UI應用程序,並且想要分離一些異步操作(加載文件或進行一些計算),那么基於期貨的方法可能更可取。 但是請注意不要在默認執行上下文中異步運行的期貨中與JavaFX組件進行任何交互(既不讀也不寫)。

如果您有一個基於actor的大型系統並且只想將UI附加到某些部分,那么在JavaFX線程上運行一些actor可能更可取。 因人而異。

在JavaFX中使用多個線程時,您需要考慮以下幾點:

  • 最終觸及場景圖的任何代碼(例如,通過更新綁定到控件的數據)必須包含在Platform.runLater 如果您使用JavaFX中的內置多線程API(即TaskService ),這將自動完成,但如果您使用任何其他多線程實用程序,則必須自己完成。

  • 您的多線程實用程序(即Akka)必須(我認為)以某種方式被告知為JavaFX事件線程留出一些空間。 如果查看服務源,您會發現在配置執行程序時需要非常小心。 我不確定這個細節,但是當我嘗試使用Scala的Future和JavaFX時,我在使用默認的ExecutionContext時在UI中發現了一些無響應,當我使用基於Service實現的自定義時,它就消失了。

ScalaFX(或據我所知的任何其他工具包)都沒有支持使用Scala Futures或Akka以一種讓你忘記上述兩點的方式,但是看一下它肯定會很有趣。

是關於可以在Swing或JavaFX線程上運行的akka​​ actor的要點。 根據Rüdiger的回答 ,它是Victor Klang的Swing Actors的一個方便的,可復制的擴展。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM