Ho letto molti articoli introduttivi su come aggiornare l'interfaccia principale nella discussione in background, e la maggior parte di essi utilizza Control.Invoke e Control.BeginInvoke. Queste sono buone soluzioni, ma ci sono due problemi:
1. Devi fare riferimento a System.Windows.Forms e poi utilizzare System.Windows.Forms
2. La struttura del codice è relativamente disordinata. (In realtà, anche questo è causato da #1)
Microsoft offre un'altra soluzione più elegante, che è System.Threading. SynchronizationContext。 Come potete vedere, non è presente in namesapce System.Windows.Forms, quindi possiamo usarlo correttamente in BusinessLaryer, Control e persino nei moduli.
Ed è molto comodo da usare, devi concentrarti solo sui seguenti due metodi:
1. Invio: invia una richiesta di aggiornamento dell'interfaccia al thread principale, bloccando il thread corrente fino al suo ritorno.
2. Post: Invia una richiesta di aggiornamento dell'interfaccia al thread principale senza bloccare il thread corrente.
In realtà, sono tutti lo stesso metodo, tranne che send è sincrono e post asincrono
Prima di Form1 form = new Form1(), l'oggetto SynchronizationContext era vuoto, e quando il form Form1 veniva istanziato, l'oggetto SynchronizationContext veniva aggiunto a questo thread. Quindi la risposta è che quando viene creato l'oggetto Control, l'oggetto SynchronizationContext viene anche creato e collegato al thread. Tutto quando si utilizza la forma InitializeComponent(); Una volta fatto questo, può ottenere un oggetto che non è NULL
Infine, la differenza tra i metodi Sendt() e Post() di SynchronizationContext:
Send() viene implementato semplicemente chiamando il delegato sul thread corrente (chiamata sincrona). Cioè, il thread UI viene chiamato direttamente sul sottothread per essere eseguito, e il sottothread continuerà a eseguire dopo il completamento dell'esecuzione del thread UI.
Post() viene implementato chiamando un delegato sul pool di thread (chiamata asincrona). Questo perché il sottothread troverà un thread dal pool di thread per ottimizzare il thread UI, e il sottothread eseguirà direttamente il proprio codice senza aspettare che il thread UI si completi. Codice di test:
Risultato:
Thread principale dell'interfaccia: 1 Filo: 5 SynchContest:1
Sommario:L'oggetto SynchronizationContext sul thread UI, sia chiamato sul thread principale che nel thread, verrà eseguito sul thread principale, quindi quando c'è molto codice che richiede tempo, farà bloccare l'interfaccia UI o farà finta la morte!
InfattiIl thread UI non utilizza la classe SynchronizationContext, ma WindowsFormsSynchronizationContextQuesto Dongdong.
Codice sorgente System.Threading.SynchronizationContext:
Codice sorgente WindowsFormsSynchronizationContext:
|