我对我对Scala中的标准演员库的理解有问题。在下面的代码中,我创建了一个简单的swing,它基本上应该测试它是否能够连接到postgreSQL服务器。然而它并没有达到那样的程度,我使用了Actor,因为UI在完成连接数据库所需的工作时会冻结。 当呃我使用这条线(意思是我用的演员,而不是一个单独的线程)Scala Actor连接到数据库时会暂停意外
PostgresCheck ! new GetInfo()
秋千将永远不会被更新。但是,如果我评论这条线并使用接下来的三条线。 (这意味着演员不会被使用)
val result = PostgresCheck.checkPostgreSQL
if (result == "OK") pgText.background = GREEN else pgText.background = RED
pgText.text = result
摆动会冻结,但约25秒后摆动将被更新。
import dbc.Database
import dbc.vendor.PostgreSQL
import java.awt.Dimension
import java.net.URI
import java.sql.Connection
import swing.event._
import swing._
import actors.Actor
import java.awt.Color._
import scala.actors.Actor._
case class Info(reply: String)
case class GetInfo()
object Example extends SimpleSwingApplication {
val pgButton = new Button("Check PostgreSQL")
val pgText = new TextArea("Not Checked Yet")
val pgPanel = new GridPanel(1, 2)
pgPanel.contents += pgButton
pgPanel.contents += pgText
def top = new MainFrame {
title = "StateChecker"
contents = pgPanel
}
listenTo(pgButton)
reactions += {
case e: ButtonClicked if (e.source.eq(pgButton)) => {
PostgresCheck ! new GetInfo()
//val result = PostgresCheck.checkPostgreSQL
//if (result == "OK") pgText.background = GREEN else pgText.background = RED
//pgText.text = result
}
}
val guiActor = new Actor {
def act() = {
loop {
react {
case e: String => {
val result = e
if (result == "OK") pgText.background = GREEN else pgText.background = RED
pgText.text = result
}
case e => println(e.toString)
}
}
}
}
guiActor.start
}
object PostgresCheck extends Actor {
def checkPostgreSQL() = {
try {
val db = new Database(myPgSQL)
val con: Connection = myPgSQL.getConnection // Freezes while doing this method
val statement = con.createStatement
if (statement.getResultSet.getMetaData.getColumnCount == 1) "OK"
else statement.getWarnings.toString
}
catch {
case e => e.toString
}
}
def act() = {
loop {
react {
case e: GetInfo => {
sender ! new Info(checkPostgreSQL)
}
}
}
}
start()
}
object myPgSQL extends PostgreSQL {
val uri = new URI("jdbc:postgresql://whatever.com")
val user = "1234"
val pass = "1234"
}
你可以在应用程序挂起时转储堆栈跟踪吗?在窗口上,在控制台窗口中,在Unix上CTRL-BREAK,'kill -QUIT pid',其中pid是进程ID。 – retronym
在标准tty设置下,CTRL- \将在Unix和Linux下生成一个QUIT信号。 –
您确定PostgresCheck的初始化程序甚至正在运行吗? (也就是说,如果你在'start()'之后放了一个'println(“Running”)',你看到它了吗?)你是否曾经将它放入guiActor的反应声明中? –