Frage

habe ich ein Problem mit meinem Verständnis der Standard Schauspieler Bibliothek in Scala. Im folgenden Code Ich habe eine einfache Schaukel erstellt, die im Grunde testen sollen, wenn es in der Lage ist zu einem PostgreSQL-Server zu verbinden. Allerdings tut es macht es so weit, ich Schauspieler, da die UI würde sonst gefrieren, während die Arbeit erforderlich machen, um die Datenbank zu verbinden. Wenn er mir diese Linie verwenden (was bedeutet, dass ich Schauspieler anstelle einem einzigen Thread verwenden)

PostgresCheck ! new GetInfo()

Die Schaukel wird nie aktualisiert werden. Allerdings, wenn ich die Zeile aus kommentieren und die nächsten drei Zeilen verwenden. (Die Schauspieler Bedeutung würde nicht verwendet werden)

      val result = PostgresCheck.checkPostgreSQL
      if (result == "OK") pgText.background = GREEN else pgText.background = RED
      pgText.text = result

Die Schaukel wird einfrieren, aber nach etwa 25 Sekunden wird das Swing aktualisiert werden.

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"
}
War es hilfreich?

Lösung

Sie haben die Nachricht außerhalb Schauspieler zu senden, so scheint es. Versuchen Sie folgendes:

Actor.actor { PostgresCheck ! new GetInfo() }

Nicht sicher, ob es hilft, aber es ist Standard beraten.

Und jetzt, wo ich darüber nachdenke, an wen die Antwort geschickt werden? Sie antworten auf den nicht vorhandenen Absender. Ich nehme an, Sie die Antwort wollen guiActor gehen, aber ich sehe nicht, dass Sie dies zu tun.

Andere Tipps

Okay, hier gehen wir, war das Problem mit der Leitung im Zusammenhang

sender ! new Info(checkPostgreSQL)

Es sollte eigentlich gewesen sein

Example.guiActor! new Info(checkPostgreSQL)

Aus irgendeinem Grund auf die Schauspieler Bibliothek im Zusammenhang es aussetzt eigentlich, wenn für die Datenbankverbindung warten und pflegen Rückkehr aufgrund eines unbekannten Absenders. Zum Beispiel ergeben sich die folgenden Zeilen in einem Ausdruck von nur einer einzigen Zeile in der Konsole mit „1“.

      val db = new Database(myPgSQL)
      println("1")
      // Freezes while doing this method
      val con: Connection = myPgSQL.getConnection 
      println("2")

Wenn Sie die oben genannte Linie zu ändern, wird die Code verhält sich wie erwartet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top