Přečetl jsem mnoho úvodních článků o tom, jak aktualizovat hlavní rozhraní v pozadí vlákna, a většina z nich používá Control.Invoke a Control.BeginInvoke. Jsou to dobrá řešení, ale jsou tu dva problémy:
1. Musíte se odvolat na System.Windows.Forms a poté použít System.Windows.Forms
2. Struktura kódu je poměrně chaotická. (Ve skutečnosti je to také způsobeno #1)
Microsoft nabízí další, elegantnější řešení, kterým je System.Threading. SynchronizationContext。 Jak vidíte, není to v namesapce System.Windows.Forms, takže ho můžeme oprávněně použít v BusinessLaryeru, Controleru a dokonce i v modulech.
A je velmi pohodlný na používání, stačí se zaměřit na následující dvě metody:
1. Odeslat: Odesílá požadavek na aktualizaci rozhraní hlavnímu vláknu, blokuje aktuální vlákno, dokud se nevrátí.
2. Post: Odešle požadavek na aktualizaci rozhraní do hlavního vlákna, aniž by blokoval aktuální vlákno.
Ve skutečnosti jsou všechny stejné metody, kromě toho, že send je synchronní a post je asynchronní
Před formou Form1 = novou Form1() byl objekt SynchronizationContext prázdný a když byl formulář Form1 instancován, objekt SynchronizationContext byl připojen k tomuto vláknu. Takže odpověď je, že když je vytvořen řídicí objekt, objekt SynchronizationContext je také vytvořen a připojen k vláknu. To vše při použití formuláře InitializeComponent(); Jakmile je to provedeno, může získat objekt, který není NULL
Nakonec rozdíl mezi metodami SynchronizationContext Sendt() a Post():
Send() je implementováno jednoduše vyvoláním delegáta na aktuálním vlákně (synchronní volání). To znamená, že vlákno UI je přímo voláno na podvlákno k vykonání a podvlákno pokračuje ve vykonávání i po dokončení dokončení vlákna UI.
Post() je implementováno voláním delegáta do poolu vláken (asynchronní volání). Je to proto, že podvlákno najde vlákno z poolu vláken, aby doladilo vlákno UI, a podvlákno přímo spustí svůj vlastní kód bez čekání na dokončení vlákna UI. Testovací kód:
Výsledek:
Hlavní vlákno UI: 1 Vlákno: 5 SynchContext:1
Shrnutí:Objekt SynchronizationContext na UI vlákně, ať už volán v hlavním vlákně nebo ve vlákně, bude vykonán na hlavním vlákně, takže když je hodně časově náročného kódu, způsobí to zamrznutí nebo předstírání smrti rozhraní UI!
VlastněVlákno UI nepoužívá třídu SynchronizationContext, ale WindowsFormsSynchronizationContextTenhle Dongdong.
Zdrojový kód System.Threading.SynchronizationContext:
Zdrojový kód WindowsFormsSynchronizationContext:
|