Wir wissen, dass es nicht möglich ist, Code auszuführen, der die Eigenschaften eines UI-Elements von einem anderen Thread als dem Thread beeinflusst, in dem das Element instanziiert wurde ... Meine Frage ist: Warum?
Ich erinnere mich, dass bei Verwendung von COM-Benutzeroberflächenelementen (in COM / Visual Basic 6.0 Tagen) alle Benutzeroberflächenelemente mithilfe von COM-Klassen und Co-Klassen erstellt wurden, die ihre Ressourcen mit einem Speichermodell speicherten, das als Thread- Local-Storage (TLS), aber ich erinnere mich, dass dies erforderlich war, weil etwas mit der Art und Weise zusammenhing, wie COM-Komponenten erstellt wurden, und nicht für .NET-UI-Elemente relevant sein sollte. Was ist der Grund, warum diese Einschränkung noch existiert?
Liegt das zugrunde liegende Betriebssystem immer noch auf COM-basierten Win32-API-Klassen für alle UI-Elemente, auch auf denen, die in einer verwalteten .NET-Anwendung manipuliert wurden?
AFAIK, es ist einfacher als selbst COM. Es geht bis auf die gute alte Windows API. Ich glaube, dass Fenster in Windows von einem Thread, Zeitraum gehört werden. Jeder Thread hat seine eigene Nachrichtenpumpe, die Nachrichten an die Fenster sendet, die er besitzt. Es ist ein ziemlich grundlegendes Konstrukt von Windows - vielleicht ein bisschen archaisch in diesen Tagen, aber grundlegend.
Ich bin der Meinung, dass diese Thread-Affinität für die Interoperabilität hilft, wenn Sie WPF in Windows Forms-Anwendungen integrieren müssen oder wenn Sie mit einem Windows-Objekt irgendwo anders in Ihrer Anwendung mit einem HWND, das Sie irgendwo haben, müssen. Es ist wahrscheinlich auch, was es älteren Versionen von Windows (XP) ermöglicht, WPF-Anwendungen ohne größere Änderungen an der Architektur des Betriebssystems selbst zu hosten.
Es klingt, als würden Sie eher auf WPF als auf generische Windows-API-Programmierung verweisen. Ich bin kein Experte für WPF-Interna, aber hier sind ein paar Dinge, warum das Behalten von UI-Manipulationen in einem UI-Thread eine gute Idee ist:
Dieser letzte Punkt bezieht sich auf die Win API. Wenn ein Fensterhandle erstellt wird, ist es an den Thread gebunden, der den CreateWindow-Aufruf ausgegeben hat. Nachrichten, die an dieses Fensterhandle gesendet werden, werden in der Nachrichtenwarteschlange platziert, die diesem Thread zugeordnet ist. Wenn dieser Thread Fenstermeldungen nicht verarbeitet, reagiert das Fenster nicht - die Benutzeroberfläche wurde eingefroren. Wenn ein anderer Thread versucht, SendMessage an dieses Fenster zu senden, wird dieser Thread ebenfalls eingefroren und wartet auf den Abschluss des synchronen Aufrufs. Das Schneegestöber schwirrt überall schnell in Hässlichkeit. Aus diesem Grund ist es wichtig, dass Sie nur Fensterhandles für Threads erstellen, die für die Verarbeitung von Fenstermeldungen vorbereitet sind.
Warum ist die Nachrichtenwarteschlange eines Fensterhandle an einen bestimmten Thread gebunden? Ich weiß es nicht, aber ich bin mir sicher, dass die Antwort nicht trivial ist.
Von Ссылка :
In der Vergangenheit erlaubt Windows die Benutzeroberfläche Elemente, auf die nur von der Thread, der sie erstellt hat. Das heisst dass ein Hintergrund Thread verantwortlich für Einige lang andauernde Aufgaben können nicht aktualisiert werden Textfeld, wenn es fertig ist. Windows tut dies, um die Integrität von UI-Komponenten. Ein Listenfeld könnte aussehen seltsam, wenn der Inhalt aktualisiert wurde durch einen Hintergrundfaden während Malerei.
Tags und Links .net user-interface multithreading