Dialog im Hintergrund anzeigen per Thread

Nach langer Zeit fühlte ich mich wieder einmal gedrängt einen Blogeintrag zu verfassen.

Momentan entwickle ich eine Software zum steuern von Pipettierrobotern. Genauer gesagt dem BioMek 2000. Das ganze ist eine sehr spezielle Anwendung und auf die Wissenschaftler unseres Unternehmens abgestimmt.

Mein Programm erstellt aus einer Exceldatei ein Script für den Roboter und lässt dieses von einer anderen Software ausführen. Meine Anwendung soll automatisch erkennen wann der Nutzer das Programm zur Ausführung des Scripts beendet hat. Soweit sogut, das funktioniert auch wunderbar. Nun wollte ich heute noch einen schicken Dialog an den Nutzer ausgeben, damit dieser weiß was genau gerade passiert und was er tun muss. Dazu hatte ich im Vorfeld schon eine WorkDialog Klasse erstellt. Mit dieser kann ein Dialog (wie ich ihn mehrfach in meiner Software brauche) angezeigt werden.

Das Problem an der Sache? Wie den Dialog anzeigen und automatisch schließen, wenn das Programm geschlossen wird?
Dazu gibt es mehrere Ansätze. Ich habe folgenden heute ausprobiert und bin sehr zufrieden.

Ein Wort als Hinweis noch: Die Klasse WorkDialog bietet an den Dialog als unschließbar und TopMost zu instanzieren.

Die Aufrufende Methode

void Run()
{			
  Process b2k = new Process();
  b2k.StartInfo.FileName = @"C:\BIOWORKS\b2krun.exe"; 
  b2k.StartInfo.Arguments = "run(\"" + "BIOSCRIPTER" + "\") /a";
			
  Thread userNotificationThread = new Thread(this.ShowBioWorkUserNotification);
  userNotificationThread.Start();
			
  try {
    b2k.Start();
    b2k.WaitForExit();
  } catch (Exception ex) {
    throw new Exception("Unable to run B2K, check your intallation!", ex);
  } finally {
    userNotificationThread.Abort();
}

Hier wird das Programm zum Ausführen des Scripts gestartet und solange gewartet bis es beendet wurde. Um das zu erreichen braucht man nur die Methode WaitForExit() nach dem Starten aufrufen.

An dieser Stelle sieht man auch das Problem nochmal. Die Methode wartet nun, wie kann ich also trotzdem einen Dialog anzeigen? Dazu wird hier ein Thread erstellt und dort die Methode ShowBioWorkUserNotification() ausgeführt.

Die Thread-Methode

void ShowBioWorkUserNotification(object inputData)
{
  WorkDialog wd = new WorkDialog(true, true);
  wd.Caption = "";
  wd.Headline = "BioWorks is running";
  wd.Message = "Please wait until the BioMek 2000 has finished his work." + Environment.NewLine + "Then close the BioWorksRun Window to " + "come back to BioScripter.";
  wd.SetWaitingIcon();
			
  wd.ShowDialog();
}

In dieser Methode wird nur mein WorkDialog instanziert (unclosable and topmost) und konfiguriert.
Damit dieser Thread nicht einfach zu Ende geht, verwende ich ShowDialog() statt nur Show(). Dadurch wird gewartet bis der Dialog geschlossen wird. Da dieser aber nicht vom Benutzer geschlossen werden kann, bleibt der Thread (und der Dialog) aktiv.

Wurde BioWorks nun vom Benutzer beendet läuft auch meine erste Methode weiter. Dort wird dann im Finally-Block der Thread mit dem Dialog beendet. Damit schließt sich auch automatisch der Dialog.

Schnell und recht einfach kann man so eine Meldung dauerhaft neben anderen Operation anzeigen lassen.

Werbung

Browser beenden mit VB.NET

Um mit VB.NET zuverlässig Browserprozesse zu schließen habe ich folgenden Code verwendet:

SetOutput("Beende Prozess " & oApp.Id & " : " & oApp.StartInfo.FileName)

oApp.CloseMainWindow()

Thread.Sleep(1000)

While oApp.HasExited = False
  SetOutput(" warte auf Prozessende...")
  oApp.CloseMainWindow()
  Thread.Sleep(1000)
End While

SetOutput("Prozess erfolgreich beendet.")

Oracle DB Verbindung mit VB.NET

So hier direkt ein kleiner Codeauszug, wie ich die Verbindung hergestellt habe:

Public Function OraConnect() As Boolean
  Dim sUser As String = "yourUserName"
  Dim sPasswd As String = "yourPassword"
  'Mit Oracle DB verbinden
  Try
    Dim sConnString = "Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP) (HOST = %DEINHOST%)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP) (HOST = %DEINHOST)(PORT = 1521))) (LOAD_BALANCE=ON) (FAILOVER=ON) (CONNECT_DATA = (SERVICE_NAME=SERVICE_RAC) (FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=10)(DELAY=5))));" & _
                        "USER=" & sUser & "; password=" & sPasswd
    _oConn.ConnectionString = sConnString
    _oConn.Open()
    Return True
  Catch ex As Exception
    'Fehlerbehandlungen - evt. E-Mail an Programmierer senden
  End Try

  Return False
End Function

Eine recht nützliche Website zu dem Thema: www.connectionstrings.com