XamlReader.Load in einem Hintergrund-Thread. Ist es möglich?

8

Eine WPF-App lädt die Benutzersteuerung aus einer separaten Datei mit XamlReader.Load() method:

%Vor%

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?

    
rem 22.03.2011, 17:20
quelle

5 Antworten

7

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.

    
JaredPar 22.03.2011, 17:25
quelle
2

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:

  1. Zerlegen Sie den XAML in kleinere Teile.
  2. Starten Sie einen neuen STA-Thread für jeden 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.
Jon 22.03.2011 17:29
quelle
1

Ich habe keine genaue Lösung, aber Sie können eine Richtung aus folgenden Links bekommen.

Ссылка

Ссылка

    
Akash Kava 22.03.2011 19:13
quelle
0

System.Xaml hat eine Klasse Xaml​Background​Reader , vielleicht könnten Sie das für sich arbeiten lassen. Parsen Sie das XAML im Hintergrundthread, aber erstellen Sie die Objekte im UI-Thread.

    
Tb. 29.04.2017 04:00
quelle
-1

Sie können eine Methode aufrufen, mit der Sie einem anderen Thread die Kontrolle geben können:

Ссылка

Es heißt .Freeze ()

    
meee 01.08.2011 15:55
quelle

Tags und Links