Laden...

Aus Thread heraus Fenster öffnen

Erstellt von userid4106 vor 12 Jahren Letzter Beitrag vor 12 Jahren 5.381 Views
Thema geschlossen
U
userid4106 Themenstarter:in
457 Beiträge seit 2006
vor 12 Jahren
Aus Thread heraus Fenster öffnen

Hallo,

vielleicht stehe ich gerade etwas auf dem Schlauch aber ich habe folgendes Problem.
Ich habe eine MVVM Anwendung die relativ groß ist. Leider verarbeiten einige Methoden so viele Daten, das währenddessen die Oberfläche stillsteht.
Jetzt könnte man die Arbeit der Methoden in Threads auslagern. Könnte... Ist aber leider zu viel Aufwand. Ich habe mir also schnell ein kleines Fenster zusammengebastelt in dem nur eine Progressbar liegt. Sobald eine Mehtode aufgerufen wird, die die Oberfläche zum Stillstand bringen könnte, startet die mein Fenster und es legt sich über die Anwendung und zeigt die Progressbar an.
Problem ist, dass die Progressbar, obwohl sie auf IsIndeterminate true steht sich nicht bewegt. Die Mehtode blockiert also auch dieses Fenster. Ok, zack das ganze mit dem Fensteraufruf in eine Klasse gelegt wie in diesem Beisspiel:
MSDN: Gewusst wie: Erstellen und Beenden von Threads (C#-Programmierhandbuch)

Anschließend bekomme ich folgenden Fehler:> Fehlermeldung:

Beim aufrufenden Thread muss es sich um einen STA-Thread handeln, da dies für viele Komponenten der Benutzeroberfläche erforderlich ist.

Verdammt... vielleicht sehe ich den Wald vor lauter Bäumen nicht mehr aber wie bekomme ich das ans rennen?!

Das Fenster kann von mir aus ruhig einfrieren. Aber das neue Fenster mit der Progressbar soll doch gefälligst funktionieren.

D
500 Beiträge seit 2007
vor 12 Jahren

Hi!

Ich muss Dir sicherlich nicht sagen, dass Deine beschriebene "Loesung" ein richtiger Hack ist und saemtlichen gaengigen und guten Softwareprinzipien widerspricht. Ich kann Dir nur davon abraten, so wie Du es jetzt implementierst. Du solltest versuchen, Teile der Applikation zu verbessern und langwierige Arbeitsschritte in den Hintergrund zu legen und nicht irgendwelche UIs (beachte Pfadfinderregel).

Du wirst eventuell mit folgendem Artikel weiterkommen, wenn auch nur unter vehementen Veto meinerseits:

Thread.SetApartmentState Method

Gruss,
DaMoe

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Second Sun,

sei mir nicht böse, wenn ich mich wirklich wundere, dass nach solanger Zeit der Beschäftigung mit C# und sovielen Fragen im Forum, immer noch solche Probleme auftauchen.

Zuerst muss ich natürlich DaMoe80 bestätigen und bestärken: Der beste - um nicht zu sagen, einzig richtige - Weg ist, die langlaufenden Aktionen in Threads auszulagern. Dann kommt es erst gar nicht zu Blockierungen. Und entsprechend kannst du auch ein Fenster mit ProgressBar aus dem GUI-Thread heraus aufrufen, ohne dass es blockiert.

Wenn ich mich mal für einen Moment auf die Idee eines dirty workaround einlasse, dann gibt es mehrere Punkte dazu zu sagen.

Für die genannte Art von Exception gilt [Hinweis] Syntaxfehler selbst lösen (Compilerfehlermeldungen) analog. Es ist zwar es formal gesehen eine Exception, aber im Grund nur, weil erst zur Laufzeit eine entsprechende Prüfung möglich ist. Aber an sich kann man die Exception abarbeiten, wie einen Syntaxfehler. Es ist also nicht mehr als ein bisschen Eigeninitiative gefragt.

Zugegeben ist damit noch nicht das Problem behoben, dass der ProgressBar weiterhin blockiert. Spätestens jetzt sind wir bei [FAQ] Warum blockiert mein GUI? Dort steht zu lesen:

Nur ein GUI-Thread

Alle Fenster sollten/müssen immer aus dem GUI-Thread erzeugt werden. Das Erzeugen von Fenster und Controls sollte nicht/nie in extra Thread verlagert werden. Wenn man das tut, kann das - so paradox das klingt - ebenfalls zum Blockieren des neue erzeugten Fensters [...] führen.

Ok, da steht nicht, wie man die Blockierung verhindern kann, wenn man das Fenster unbedingt aus einem anderen Thread öffnen will. Das hat einen einfachen Grund: Man sollte ein Fenster nicht/nie aus einem anderen Thread öffnen. Damit sind wir wieder bei dem eingangs gesagten.

Wenn ich mich einmal mehr auf die Idee eines dirty workaround einlasse, dann sollte die Ursache eigentlich dennoch klar sein. Ein GUI-Thread ist ein Thread, der Application.Run ausführt. Application.Run sorgt für die Nachrichtenverarbeitung, ohne die kein Fenster bedienbar ist.

Insgesamt sollte das Problem unter Beachtung von [Hinweis] Wie poste ich richtig? Punkt 1.1.1 und 1.1 lösbar sein.

herbivore

Thema geschlossen