ScalaFX 和猫效应

问题描述 投票:0回答:1

我正在尝试将 Cats Effect 集成到 ScalaFX 桌面应用程序中,但在执行任务时遇到问题。我想运行后台线程/光纤来在显示窗口时对其进行初始化。我认为我正在做的是:

  1. 在阻塞 IO 上启动 JavaFX 应用程序。
  2. JavaFX 正在做很多事情,包括启动自己的线程之类的。我不确定这是否重要。
  3. 在“JavaFX应用程序线程”线程上,控制器的可初始化方法正在运行(通过println确认),并创建我想要执行的IO。
  4. 我正在创建 Supervisor 在后台执行它。
  5. 它没有打印“Hello”。

我尝试了一些解决方案,例如调用 SupervisorIO.evalOn() 而不是下面的简单调用。我尝试在 Supervisor#supervise 创建的线程上调用“join”来尝试强制它执行,但没有任何反应。

我将应用程序简化为如下所示(FXML 只是一个 BorderPane 和一个 Label,它配置控制器类;我认为您不需要看到它):

object CatsTest extends IOApp.Simple {
  override def run: IO[Unit] = {
    IO.blocking {
      Application.launch(classOf[CatsTestMain])
    }
  }
}

class CatsTestMain extends Application {
  override def start(primaryStage: Stage): Unit = {
    val screen = getClass.getResource("/main-screen.fxml")
    val loader = new FXMLLoader()
    loader.setLocation(screen)
    val root: Parent = loader.load[javafx.scene.Parent]
    val controller = loader.getController[MainController]()

    primaryStage.setScene(new Scene(new javafx.scene.Scene(root)))
    primaryStage.show()
  }
}

class MainController extends Initializable {
  override def initializable(location: URL, resources: ju.ResourceBundle): Unit = {
    println("in controller")
    val supervisor = Supervisor[IO](await=true)
    supervisor.use { supervisor =>
      supervisor.supervise(IO.println("Hello"))
    }
  }
}

我不知道是否需要封送回原始线程才能使用 Cats 的资源,或者问题是什么。我是 Cats Effect 的新手,这是我一段时间以来编写的第一个不必然使用 Akka/Pekko 的应用程序,所以这似乎是学习它的好方法,但我忍不住我认为我制造的问题比我解决的问题还要多,而不仅仅是使用 Future 对象。

multithreading scala javafx scala-cats scalafx
1个回答
0
投票

这里有两个问题:

第一个也是最重要的一个是

supervisor.use
返回一个
IO
,这只是计算的描述,仅此而已。它需要显式地运行或与其他
IOs
一起排序。这是编写cats-effect应用程序所需的基础知识,
IO
只是描述、值,而不是正在运行的计算的处理程序;与
Future

相反 您想要用于这种互操作的是
Dispatcher
,而不是
Supervisor
https://typelevel.org/cats-effect/api/3.x/cats/effect/std/Dispatcher.html 为您提供
unsafeRunAndForget
以发送
IO
在后台运行。

其次,您对生命周期的管理不善。您不想为每个

Dispatcher
创建和销毁一个
IO
来执行。理想情况下,
MainController
应该收到一个已经分配的
Dispatcher
,并且其他东西必须确保它在不再需要时正确关闭。

第三,如果您计划运行的

IOs
会影响界面,则需要在JavaFX的适当线程上运行。


所以这似乎是学习它的好方法

就我个人而言,我不同意。

  • 首先,
    IO
    更适合必须处理并发的 Web 服务器。
  • 其次,对于新手来说,这类需要双向互操作的应用程序实际上更难编写。因为他们希望您精通 JavaFX 内部结构和 cats-effect 执行模型。

话虽如此。在过去的几年里,很多人都建造了类似的东西。您可以在 Discord 服务器中寻求建议和资源。

© www.soinside.com 2019 - 2024. All rights reserved.