Prebral sem veliko uvodnih člankov o tem, kako posodobiti glavni vmesnik v ozadni niti, in večina uporablja Control.Invoke in Control.BeginInvoke. To so dobre rešitve, vendar obstajata dve težavi:
1. Morate se sklicevati na System.Windows.Forms in nato uporabiti System.Windows.Forms
2. Struktura kode je razmeroma neurejena. (Pravzaprav je to tudi posledica #1)
Microsoft ponuja še eno, bolj elegantno rešitev, in sicer System.Threading. SynchronizationContext。 Kot vidite, ni v namesapce System.Windows.Forms, zato ga lahko upravičeno uporabljamo v BusinessLaryerju, Controlerju in celo modulih.
In je zelo priročna za uporabo, osredotočiti se morate le na naslednji dve metodi:
1. Pošlji: Pošlje zahtevo za posodobitev vmesnika glavni niti in blokira trenutno nit, dokler se ne vrne.
2. Post: Pošlje zahtevo za posodobitev vmesnika glavni niti, ne da bi blokiral trenutno nit.
Pravzaprav so vse iste metode, le da je send sinhron, post pa asinhron
Pred obrazcem Form1 = novim Form1() je bil objekt SynchronizationContext prazen, in ko je bila obrazec Form1 instanciran, je bil objekt SynchronizationContext dodan tej niti. Torej, odgovor je, da ko se ustvari kontrolni objekt, objekt SynchronizationContext je prav tako ustvarjen in priključen na nit. Vse to pri uporabi oblike InitializeComponent(); Ko je to storjeno, lahko dobi objekt, ki ni NULL
Nazadnje, razlika med metodama Sendt() in Post() za SynchronizationContext:
Send() je implementiran tako, da preprosto pokličemo delegata na trenutni niti (sinhroni klic). To pomeni, da se UI nit neposredno pokliče na podnit za izvajanje, podnit pa se izvaja tudi po zaključku izvajanja UI niti.
Post() se implementira z klicem delegata v nitnem bazenu (asinhroni klic). To je zato, ker podnit najde nit iz bazena niti za nastavitev UI niti, podnit pa neposredno izvede svojo kodo brez čakanja, da se UI nit dokonča. Testna koda:
Rezultat:
Glavna nit uporabniškega vmesnika: 1 Nit: 5 SynchContext:1
Povzetek:Objekt SynchronizationContext v UI niti, ne glede na to, ali je klican v glavni niti ali v niti, se bo izvajal na glavni niti, zato se ob preveliki zamudni kodi uporabniški vmesnik zamrzne ali ponaredi smrt!
V bistvuUI nit ne uporablja razreda SynchronizationContext, ampak WindowsFormsSynchronizationContextTa Dongdong.
Izvorna koda System.Threading.SynchronizationContext:
Izvorna koda WindowsFormsSynchronizationContext:
|