Grund für die Thread-Beschränkung des .NET-UI-Elements

8

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?

    
Charles Bretana 01.06.2010, 23:47
quelle

3 Antworten

2

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.

    
Dave Markle 01.06.2010, 23:55
quelle
1

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:

  1. Vermeide Deadlocks. Wenn mehrere Threads ausgeführt werden, müssen alle freigegebenen Ressourcen durch eine Art von Sperre geschützt werden. Wenn mehrere Sperren vorhanden sind, besteht ein hohes Risiko, in einem Deadlock zu stecken - Thread A besitzt Sperre 1, wartet aber auf Sperre 2, Thread B besitzt Sperre 2, wartet aber auf Sperre 1. Dies kann durch strikte Reihenfolge vermieden werden Lock Erwerb, aber die menschliche Natur fällt zu kurz.
  2. Verringern Sie die Notwendigkeit teurer Sperren. Wenn Sie alle UI-Ops für die Ausführung im UI-Thread benötigen, können Sie viele Sperren zum Schutz interner Daten beseitigen.
  3. Reduzieren Sie das Risiko, Fensterhandles zu erstellen, die Threads gehören, die keine Nachrichtenschleifen haben.

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.

    
dthorpe 02.06.2010 00:13
quelle
0

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.

    
Ed Power 02.06.2010 00:09
quelle