Laden...

GUI aus Thread aktualisieren

5 Antworten
1,874 Aufrufe
Letzter Beitrag: vor 17 Jahren
GUI aus Thread aktualisieren

Hallo Gemeinde,

ich habe eine WPF-Anwendung mit einem Frontend und für langwierige Aktionen wie einen CSV-Import oder Webabfragen einzelne Threads, damit die Anwendung nicht "einschläft". Leider kann ich aber aus diesen externen Threads nicht die Statusleiste meines Frontends überschreiben, da dies ein externer Thread wohl nicht darf. Das beschriebene Invoke habe ich nicht gefunden. Gibt es das vielleicht nur in Windows.Forms? In meiner Verzweiflung habe ich schon eine globale Variable mit dem Inhalt der Statusleiste eingeführt, die alle Threads beschreiben können und ein DispatcherTimer liest diese Variable aus und schreibt den Inhalt ins Frontend. Aber das ist nichts halbes und nichts ganzes. Entweder ich polle hier im Millisekundenbereich oder ich verpasse Infos, da sie bereits wieder überschrieben wurden, bevor sie der Timer abruft. Wie kann ich also direkt aus einem Thread, aufgerufen mit:


            Thread threadRequestDB = new Thread(RequestDB);
            threadRequestDB.SetApartmentState(ApartmentState.STA);
            threadRequestDB.Start();

auf das Frontend zugreifen? Und das wie gesagt bei einer WPF-Anwendung. Ein ctrl.InvokeRequired finde ich nirgends.

MAY THE FORCE BE WITH YOU !!!

Hallo,

auf der richtigen Fährte bist du schon 🙂 Mit Invoke den Thread auf die GUI zugreifen zu lassen ist vollkommen richtig. Nur sind die entsprechenden Methoden nicht mehr direkt in irgend einem GUI Element sondern jedes Element das irgendwie von DispatcherObject abgeleitet ist, besitzt ein Dispatcher Property über das die Funktionen aufgerufen werden müssen.

Baka wa shinanakya naoranai.

Mein XING Profil.

Hi,
InvokeRequired aus WinForms-Zeiten ist was anderes als der WPF-Dispatcher. Man muss also etwas umdenken. Der Dispatcher verwaltet mehrere Warteschlagen mit unterschiedlichen Prioritäten, und alle Aktionen in WPF werden über ihn abgewickelt. Insofern kann man ihn wunderbar benutzen um kleine Aktionen (oder kleine Häppchen einer großen) auf dem GUI-Thread durchzuführen.
Wenn man nun aus einem richtigen Thread auf die GUI zugreifen will, kann man das auch über den Dispatcher machen:
Man holt sich den Dispatcher der GUI (nicht des Workerthreads, sprich Dispatcher.Current im Worker wird nicht funktionieren) und kann dort seine Aktion per BeginInvoke (oder Invoke) ausführen.

Kann man auch eine Funktion mit Parametern aufrufen, welche dann ihrerseits auf das Frontend zugreift. Also etwa so:


UI.Dispatcher.BeginInvoke(DispatcherPriority.Normal, UI.fillFields(wert1, wert2);
...
public void fillFields(string wert1, string wert2)
{
label1.Text = wert1;
label2.Text = wert2;
}

MAY THE FORCE BE WITH YOU !!!

Hallo LordVader,

ja, das geht. Dazu musst du aber delegates verwenden.

Also so:


private delegate void myDelegate (string wert1, string wert2);

UI.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new myDelegate(UI.fillFields),new object[]{wert1, wert2});
...
public void fillFields(string wert1, string wert2)
{
label1.Text = wert1;
label2.Text = wert2;
}

Habe es nur schnell gecoded, syntaxfehler sind also möglich =)

Weitere Infos findest du hier [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke)

Gruss
Michael