Ich habe viele Einführungsartikel darüber gelesen, wie man die Hauptoberfläche im Hintergrundthread aktualisiert, und die meisten verwenden Control.Invoke und Control.BeginInvoke. Das sind gute Lösungen, aber es gibt zwei Probleme:
1. Du musst auf System.Windows.Forms zugreifen und dann System.Windows.Forms verwenden
2. Die Codestruktur ist relativ chaotisch. (Tatsächlich wird das auch durch #1 verursacht)
Microsoft bietet eine weitere, elegantere Lösung an, nämlich System.Threading. SynchronizationContext。 Wie Sie sehen, ist es nicht in namesapce System.Windows.Forms, daher können wir es rechtmäßig in BusinessLaryer, Controler und sogar Modulen verwenden.
Und es ist sehr praktisch in der Anwendung, du musst dich nur auf die folgenden zwei Methoden konzentrieren:
1. Senden: Sendet eine Interface-Update-Anfrage an den Hauptthread und blockiert den aktuellen Thread, bis er zurückkehrt.
2. Posten: Sendet eine Interface-Update-Anfrage an den Hauptthread, ohne den aktuellen Thread zu blockieren.
Tatsächlich sind sie alle nach derselben Methode, außer dass Senden synchron und Post asynchron ist
Vor Form1-Form = neuer Form1() war das SynchronizationContext-Objekt leer, und als das Form1-Formular instanziiert wurde, wurde das SynchronizationContext-Objekt an diesen Thread angehängt. Die Antwort ist also, dass wenn das Control-Objekt erstellt wird, das SynchronizationContext-Objekt wird ebenfalls erstellt und an den Thread angehängt. Alle bei Verwendung der Form InitializeComponent(); Sobald dies erledigt ist, kann es ein Objekt erhalten, das nicht NULL ist
Schließlich der Unterschied zwischen den Sendt()- und Post()-Methoden von SynchronizationContext:
Send() wird einfach dadurch implementiert, dass der Delegate auf dem aktuellen Thread (synchroner Aufruf) aufgerufen wird. Das heißt, der UI-Thread wird direkt auf dem Subthread zum Ausführen aufgerufen, und der Subthread wird nach Abschluss des UI-Threads weiter ausgeführt.
Post() wird implementiert, indem ein Delegat im Thread-Pool (asynchroner Aufruf) aufgerufen wird. Das liegt daran, dass der Subthread einen Thread aus dem Threadpool findet, um den UI-Thread abzustimmen, und der Subthread führt seinen eigenen Code direkt aus, ohne darauf zu warten, dass der UI-Thread fertig ist. Testcode:
Ergebnis:
UI-Hauptthread: 1 Faden: 5 SynchContext:1
Zusammenfassung:Das SynchronizationContext-Objekt im UI-Thread, egal ob im Hauptthread oder im Thread, wird auf dem Hauptthread ausgeführt, sodass bei viel zeitaufwändigem Code die UI-Schnittstelle einfriert oder den Tod vortäuscht!
TatsächlichDer UI-Thread verwendet nicht die SynchronizationContext-Klasse, sondern WindowsFormsSynchronizationContextDieser Dongdong.
System.Threading.SynchronizationContext-Quellcode:
WindowsFormsSynchronizationContext-Quellcode:
|