Ich erstelle ein SolidColorBrush
auf einem Nicht-GUI-Thread und möchte es an einen GUI-Thread übergeben um es anzuzeigen, aber ich bekomme InvalidOperationException
: The calling thread cannot access this object because a different thread owns it.
(auch wenn ich versuche Freeze();
it) . Wie übergebe ich ein Objekt, das in Thread X erstellt wurde, an Thread Y?
Ich weiß, dass ich dieses SolidColorBrush
-Objekt im GUI-Thread mit Dispatcher
erstellen kann, aber das würde alles komplizieren ... Ich möchte es im Worker-Thread erstellen.
Zusätzliche Details:
Ich initialisiere einige statische Delegaten in einer statischen Klasse, um Nachrichten von der Business-Schicht zur GUI zu senden:
%Vor%Initialisierung (im GUI-Thread):
%Vor%Dann benutze ich es in einem anderen (nicht-gui) Thread:
%Vor% solange GuiMessage
ist:
Sie können wpf-Ressourcen in einem anderen Thread erstellen, wenn Sie sie einfrieren , danach das Element kann an einen anderen Thread oder den Gui-Thread übergeben werden. Denken Sie daran, dass ein einmal eingefrorenes Objekt nur geändert werden kann, indem Sie eine Kopie erstellen und diese Kopie verwenden. Sie können keine Objekte einfrieren, an die Bindungen oder Animationen angehängt sind.
Sie müssen einen Delegaten verwenden, um das Steuerelement sicher aufzurufen.
Verwenden Sie
Steuerung.Invozieren
oder
Control.BeginInvoke
für diesen Zweck.
%Vor%Wenn Sie den Delegaten nicht verwenden, um sie sicher aufzurufen, erhalten Sie die Ausnahme.
Überprüfen Sie diese Links:
Wie man die GUI von einem anderen Thread in aktualisiert C #? Linkbeschreibung hier eingeben
Sie sollten den Dispatcher verwenden.
Sie können eine Klasse erstellen, die einen Dispatcher enthält, der auf einem Hauptthread erstellt wurde, und ihn über Ihren Container in die Klasse injizieren, die in einem Hintergrundthread ausgeführt wird, der mit Ihrem Hauptthread interagieren soll.
%Vor% Erstellen Sie die Instanz von UiDispatcher
zu einem Zeitpunkt, an dem Sie sicher sind, dass Sie sich im UI-Thread befinden, z. B. während der Initialisierung Ihrer Anwendung. Stellen Sie mithilfe Ihres Dependency-Injection-Containers sicher, dass nur eine Instanz dieser Klasse erstellt und in eine andere Klasse importiert wird, die sie benötigt, und verwenden Sie sie zum Erstellen / Bearbeiten Ihrer UI-Komponenten.
Ich habe den Code ausgewählt, um zu überprüfen, ob der Konstruktor von UiDispatcher
im Hauptthread von dieser Antwort ausgeführt wird.
Die Sache ist, dass Sie auf dem UI-Thread nicht etwas verwenden können, das in einem anderen Thread erstellt wurde. Sie müssen also Ihren Hintergrundthread an den UI-Hauptthread delegieren, unabhängig davon, welche UI-Elemente betroffen sind.
Tags und Links wpf c# multithreading