| 

.NET C# Java Javascript Exception

4
Hallo zusammen,

wenn aus meiner WPF-Anwendung weitere (WPF-)Fenster geöffnet werden, muss der User teilweise 1 - 2 Sekunden warten bis die Fenster angelegt und dargestellt sind.
Meine Idee war deshalb einen Art lokalen Cache zu erstellen, in dem ein anderer Thread im Hintergrund Fenster-Objekte "auf Vorrat" erzeugt.
Soll nun ein Fenster angezeigt werden, kann ein fertiges Fenster-Objekt aus dem Cache geholt und nur noch sichtbar geschaltet.

Im Prinzip funktioniert das auch schon - solange die Vorrat-Fenster im Haupt-Thread erstellt werden. Sobald ich die Objekte von einem zweiten Thread erstellen möchte, gibt es nur Probleme.

Nachdem ich mehrmals böse STA-Thread - Fehlermeldungen erhalten habe, habe ich es auf die in WPF empfohlende Art gemacht und nutze einen Dispatcher.
Bei einem Dispatcher scheint aber, rein technisch, im Hintergrund kein neuer Thread angelegt zu werden. Meine Anwendung blockiert fast komplett bis sich der 2. Thread beendet hat.

Hat jemand eine Idee wie man so etwas elegant lösen kann?
Für einen solchen Fall muss es doch Musterlösungen geben!? Das scheint mir eine alltägliche Anforderung zu sein.

Im Haupt- WPF-Fenster:

System.Threading.Thread thread = new System.Threading.Thread(
new System.Threading.ThreadStart(
delegate()
{

this.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.ApplicationIdle,
new Action(
delegate()
{

//Statische Methode der statischen Cache-Klasse aufrufen
MeinCache.CreateElements();
}
));
}
));


thread.Start();
17.10.2012
Silvia1963 320 1 2 7
1
Wenn ich das richtig verstanden habe, gibt es auch in WPF-Programmen immer nur einen UI-Thread. Und nur der kann UI-Elemente erzeugen und darstellen.

Von daher wäre es m.M.n. sehr schwierig, wenn nicht gar unmöglich UI-Elemente in einem extra Thread zu erzeugen und im UI-Thread anzuzeigen.

Ich kann mich da aber auch irren und lasse mich gern eines Besseren belehren :)
Andreas Richter 17.10.2012
1
@Andreas: Im Prinzip schon, aber... Auch ein WPF-Programm kann mehrere UI-Threads haben, z.B. einen pro top-Level-Fenster. Siehe z.B. http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/ und den von dort verlinkten MSDN-Artikel. Man kann nur nicht UI-Elemente aus einem anderen Thread heraus manipulieren als dem, in dem sie erzeugt wurden. Und ob das dann Silvia noch was nutzt - ich weiß nicht...
Matthias Hlawatsch 17.10.2012
1 Antwort
3
Der Sinn von Dispatcher.Invoke() ist, einen Thread-Wechsel herbeizuführen in den Thread, in dem das entsprechende UI-Element erzeugt wurde - weil ein UI-Element eben nur dort manipuliert werden darf. Wenn Du also einen zweiten Thread aufmachst, dort aber Dispatcher.Invoke aufrufst, landest Du wieder dort, wo Du hergekommen bist - im UI-Thread. Deshalb blockiert Deine Anwendung. Der zweite Thread wird zwar angelegt und gestartet, aber quasi sofort wieder verlassen, und die eigentliche Arbeit findet doch im UI-Thread statt.

Je nachdem, wie die einzelnen Fenster zueinander in Beziehung stehen, könnte es evtl. helfen, pro Fenster einen eignen UI-Thread zu starten. Siehe dazu http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/ und den von dort verlinkten MSDN-Artikel. Vor allem aber würde ich Dir empfehlen zu analysieren, warum das Öffnen der Fenster so lange dauert und ob Du nicht besser diese Zeit verkürzen kannst.
17.10.2012
Matthias Hlawatsch 13,2k 4 9
1
Danke für den Link, Matthias. Mehrere UI-Threads waren mir bisher unbekannt.
Andreas Richter 18.10.2012
Vielen Dank für Deine Antwort. Ich habe mich die letzten Stunden in das Thema Threading, Dispatcher tief eingelesen. Auch den Link zu Deiner empfohlenen Seite habe ich mir angeschaut. Es scheint tatsächlich so, als sei meine Idee eines lokalen Window-Caches nicht realisierbar.
Silvia1963 19.10.2012

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH