Jeg har lest mange introduksjonsartikler om hvordan man oppdaterer hovedgrensesnittet i bakgrunnstråden, og de fleste bruker Control.Invoke og Control.BeginInvoke. Dette er gode løsninger, men det er to problemer:
1. Du må referere til System.Windows.Forms, og deretter bruke System.Windows.Forms
2. Kodestrukturen er relativt rotete. (Faktisk skyldes dette også #1)
Microsoft tilbyr en annen, mer elegant løsning, nemlig System.Threading. SynchronizationContext。 Som du ser, er det ikke i namesapce System.Windows.Forms, så vi kan med rette bruke det i BusinessLaryer, Controler og til og med moduler.
Og det er veldig praktisk å bruke, du trenger bare å fokusere på følgende to metoder:
1. Send: Sender en grensesnittoppdateringsforespørsel til hovedtråden, og blokkerer den nåværende tråden til den returnerer.
2. Post: Sender en forespørsel om grensesnittoppdatering til hovedtråden uten å blokkere den nåværende tråden.
Faktisk er de alle samme metode, bortsett fra at send er synkron og post er asynkron
Før Form1-form = ny Form1(), var SynchronizationContext-objektet tomt, og når Form1-formen ble instansiert, ble SynchronizationContext-objektet lagt til denne tråden. Så svaret er at når Control-objektet opprettes, SynchronizationContext-objektet opprettes og knyttes også til tråden. Alt dette når man bruker formen InitializeComponent(); Når dette er gjort, kan den hente et objekt som ikke er NULL
Til slutt, forskjellen mellom Sendt()- og Post()-metodene i SynchronizationContext:
Send() implementeres ved ganske enkelt å kalle delegaten på den nåværende tråden (synkront kall). Det vil si at UI-tråden kalles direkte på undertråden for å kjøre, og undertråden vil fortsette å kjøre etter at UI-tråden er fullført.
Post() implementeres ved å kalle en delegat i trådpoolen (asynkront kall). Dette er fordi undertråden vil finne en tråd fra trådpoolen for å justere UI-tråden, og undertråden vil direkte kjøre sin egen kode uten å vente på at UI-tråden skal fullføres. Testkode:
Utfall:
UI-hovedtråd: 1 Tråd: 5 SynchContext:1
Sammendrag:SynchronizationContext-objektet på UI-tråden, enten det kalles på hovedtråden eller i tråden, vil bli kjørt på hovedtråden, så når det er mye tidkrevende kode, vil det føre til at UI-grensesnittet fryser eller later som det dør!
FaktiskUI-tråden bruker ikke SynchronizationContext-klassen, men WindowsFormsSynchronizationContextDenne Dongdong.
System.Threading.SynchronizationContext-kildekode:
WindowsFormsSynchronizationContext-kildekode:
|