Eine WPF-App lädt die Benutzersteuerung aus einer separaten Datei mit XamlReader.Load()
method:
Der Prozess dauert aufgrund der Größe der Datei einige Zeit, sodass die Benutzeroberfläche für einige Sekunden eingefroren wird.
Um die App responsiv zu halten, versuche ich einen Hintergrund-Thread zu verwenden, um den Teil des Vorgangs auszuführen, der nicht direkt in die UI-Aktualisierung einfließt.
Beim Versuch, BackgroundWorker
zu verwenden, habe ich einen Fehler erhalten: Der aufrufende Thread muss STA sein, weil viele UI-Komponenten dies erfordern
Also ging ich einen anderen Weg:
%Vor%Dies löst nichts, weil alle zeitaufwendigen Operationen im UI-Thread verbleiben.
Wenn ich das versuche, mache ich alle Parsing im Hintergrund:
%Vor%Ich habe eine Ausnahme: Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, weil ein anderer Thread es besitzt. (Im geladenen Benutzersteuerelement sind andere Steuerelemente vorhanden, die möglicherweise den Fehler)
Gibt es eine Möglichkeit, diese Operation so auszuführen, dass die Benutzeroberfläche reagiert?
Das Laden eines Hintergrundthreads durch den XAML ist im Wesentlichen ein Nicht-Starter. WPF-Komponenten haben Thread-Affinität und sind in der Regel nur aus den Threads verwendbar, die sie erstellt haben. Durch das Laden eines Hintergrundthreads wird die Benutzeroberfläche reaktionsfähig, es werden jedoch Komponenten erstellt, die nicht in den UI-Thread eingefügt werden können.
Die beste Option, die Sie hier haben, besteht darin, die XAML-Datei in kleinere Teile zu zerlegen und sie inkrementell in den UI-Thread zu laden. Achten Sie dabei darauf, dass zwischen jeder Ladeoperation eine Nachricht gepumpt wird. Möglicherweise verwenden Sie BeginInvoke
für das Objekt Dispatcher
, um die Ladevorgänge zu planen.
Wie Sie herausgefunden haben, können Sie XamlReader.Load
nicht verwenden, es sei denn, der Thread ist STA. Wenn dies der Fall ist, müssen Sie eine Nachrichtenpumpe starten und den gesamten Zugriff auf die damit erzeugten Steuerelemente trichterförmig verteilen. Dies ist ein grundlegender Weg, wie WPF funktioniert, und Sie können nicht dagegen vorgehen.
Ihre einzigen wirklichen Optionen sind:
Load
-Aufruf. Nachdem Load
zurückgegeben wurde, muss der Thread eine Nachrichtenschleife starten und die von ihm erstellten Steuerelemente verwalten. Ihre Anwendung muss die Tatsache berücksichtigen, dass verschiedene Steuerelemente jetzt verschiedenen Threads gehören. Tags und Links wpf c# multithreading xamlreader