C# Seltsames Problem mit Backgroundworker

locomarco

Commander
Registriert
Aug. 2009
Beiträge
2.446
Hi,
ich bin grade dabei ne kleine GUI für nen Minecraft Server zu erstellen.

Als erstes hier mal wie ich Java (der Server ist eine ausführbare *.jar Datei) starte:

Code:
startinfo.FileName = LocateJava();
startinfo.Arguments = " -XX:+UseFastAccessorMethods -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:ParallelGCThreads=2 -XX:+CMSIncrementalPacing -XX:+UseAdaptiveGCBoundary -XX:SurvivorRatio=16 -XX:NewRatio=6 -XX:UseSSE=3 -Xmn102M -Xmx1024M -Xms1024M -jar \"" + Properties.Settings.Default.server_jar + "\" nogui"
startinfo.UseShellExecute = false;
startinfo.CreateNoWindow = true;
startinfo.RedirectStandardInput = true;
startinfo.RedirectStandardOutput = true;
startinfo.RedirectStandardError = true;

"server_jar" wird vorher mit einem OpenFileDialog festgelegt.

Mit drücken des Startbuttons wird dann Java gestartet und 2 Backgroundworker die permanent StandartError und StandartOutput Zeilenweise lesen.

Code:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            backgroundWorker1.WorkerSupportsCancellation = true;
            try
            {
                while (java.HasExited == false)
                {
                    richTextBox1.AppendText(java.StandardError.ReadLine() + "\n");
                    System.Threading.Thread.Sleep(50);
                }

            }
            catch (Exception bw1_exc)
            {
                MessageBox.Show(bw1_exc.ToString());
            }
            backgroundWorker1.CancelAsync();
        }
Der Code für den 2. Backgroundworker ist gleich, nur das er den StandartOutput in eine zweite richTextBox schreibt.


Mein erstes Problem ist das mein Programm nicht beim Debuggen funktioniert
Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement richTextBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
Und das zweite ist, das ich nicht weiß wie ich Java in einem anderen Verzeichnis starten kann. Java soll in dem Verzeichnis gestartet werden in dem die server *.jar liegt, sonst funktionierts nicht.
Das heißt momentan muss ich immer das Programm immer erst in den Server Ordner kopieren, was ziemlich nervig ist und so auch nicht gedacht ist.

Hoffentlich könnt ihr mir dabei helfen. Ich bin was das Programmieren angeht noch ziemlich am Anfang :p


Grüße
 
Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement richTextBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.

einfach im google "crossthread exception" eingeben, das loest dein problem (oder eben die komplette fehlermeldung in deutsch).

Zum 2. kann ich dir leider ned helfen
 
Ich hatte ganz vergessen nach der Exception zu googlen...
Jetzt hab ichs getan und bin noch verwirrter als zuvor. Dieses Invoke ist zu hoch für mich :freak:
 
Du kannst deine Bearbeitung eines Controls nur aus dem Thread heraus ausführen, welches dein Control/Prozess/Thread gestartet hat. Ist ungefähr zu vergleichen mit den Owner Rechten auf eine Datei in einem Dateisystem, nur dass du dort eine ausgeklügelte Rechteverwaltung hast...
Um wieder zum Thema zurück zu kommen: Du musst deine Method Invoken, sprich aus dem Thread wo sie sich befindet in den Ursprungsthread "weiterleiten".

Versuch dir es selbst anzueignen, dann ist der Lerneffekt größer, glaub mir:
http://www.csharphelp.com/2006/05/dynamic-method-invocation-in-c-using-reflection/
http://www.wer-weiss-was.de/theme205/article4240892.html

Als nettes Beispielprojekt: http://www.codeproject.com/KB/cs/FastMethodInvoker.aspx

Viele Grüße,
Fire

EDIT: Grad noch ein ähnliches Problem hier gefunden: https://www.computerbase.de/forum/threads/treeview-aus-background-thread-fuellen.832028/
 
Zuletzt bearbeitet:
Ich hab schon kapiert warum das nicht geht bzw. wie das funktioniert.
Ich bekomms nur nich hin ^_^

Ich werd aber mal deine Links noch anschauen, danke.
 
Naja, es ist denkbar einfach:

Code:
try
       {
            this.BeginInvoke(new MethodInvoker(() => this.DeineMethode()));
        }

      catch (ThreadInterruptedException)
      {
        // Invoke wurde unterbrochen... 
      }
      finally
      {
        // Mach deine abschließende Arbeiten hier...
      }
 
Zurück
Oben