Olen lukenut monia johdantoartikkeleita siitä, miten pääkäyttöliittymä päivitetään taustaketjussa, ja suurin osa niistä käyttää Control.Invokea ja Control.BeginInvokea. Nämä ovat hyviä ratkaisuja, mutta ongelmia on kaksi:
1. Sinun tulee viitata System.Windows.Formsiin ja käyttää sitten System.Windows.Formsia
2. Koodirakenne on melko sekava. (Itse asiassa tämäkin johtuu kohdasta #1)
Microsoft tarjoaa toisen, tyylikkäämmän ratkaisun, System.Threadingin. SynchronizationContext。 Kuten näet, sitä ei ole namesapce System.Windows.Formsissa, joten voimme oikeutetusti käyttää sitä BusinessLaryerissa, Controlerissa ja jopa moduuleissa.
Ja se on erittäin kätevä käyttää, sinun tarvitsee keskittyä vain seuraaviin kahteen menetelmään:
1. Lähetä: Lähettää rajapinnan päivityspyynnön pääsäikeeseen, estäen nykyisen säikeen kunnes se palaa.
2. Julkaisu: Lähettää rajapinnan päivityspyynnön pääsäikeeseen, estämättä nykyistä säikettä.
Itse asiassa ne ovat kaikki samaa menetelmää, paitsi että send on synkroninen ja post asynkroninen
Ennen kuin Form1-form = uusi Form1(), SynchronizationContext-objekti oli tyhjä, ja kun Form1-muoto käynnistettiin, SynchronizationContext-objekti liitettiin tähän säikeeseen. Joten vastaus on, että kun Control-objekti luodaan, SynchronizationContext-objekti luodaan myös ja liitetään säikeeseen. Kaikki käytettäessä muotoa InitializeComponent(); Kun tämä on tehty, se voi saada objektin, joka ei ole NULL
Lopuksi, ero Sendt()- ja Post()-metodien välillä SynchronizationContextissa:
Send() toteutetaan yksinkertaisesti kutsumalla nykyisen säikeen edustajaa (synkroninen kutsu). Toisin sanoen käyttöliittymäsäie kutsutaan suoraan alisäikeessä suoritettavaksi, ja alisäie jatkaa suoritustaan käyttöliittymäsäikeen suorituksen jälkeen.
Post() toteutetaan kutsumalla säikepoolin edustaja (asynkroninen kutsu). Tämä johtuu siitä, että alisäie löytää säikeen säiepoolista virittämään käyttöliittymäsäikettä, ja alisäie suorittaa suoraan oman koodinsa odottamatta käyttöliittymäsäikeen valmistumista. Testikoodi:
Tulos:
UI:n pääketju: 1 Ketju: 5 SynchContext:1
Yhteenveto:SynchronizationContext-objekti käyttöliittymäsäikeessä, olipa se sitten kutsuttu pääsäikeessä tai säikeessä, suoritetaan pääsäikeessä, joten kun koodia vie paljon aikaa, käyttöliittymä jäätyy tai feikkaa kuolemaa!
Itse asiassaUI-säikeessä ei käytetä SynchronizationContext-luokkaa, vaan WindowsFormsSynchronizationContextTämä Dongdong.
System.Threading.SynchronizationKontekstin lähdekoodi:
WindowsFormsSynchronizationContext source code:
|