Jag har läst många introduktionsartiklar om hur man uppdaterar huvudgränssnittet i bakgrundstråden, och de flesta använder Control.Invoke och Control.BeginInvoke. Detta är bra lösningar, men det finns två problem:
1. Du måste referera till System.Windows.Forms och sedan använda System.Windows.Forms
2. Kodstrukturen är relativt rörig. (Faktiskt orsakas detta också av #1)
Microsoft erbjuder en annan, mer elegant lösning, nämligen System.Threading. SynchronizationContext。 Som du kan se finns det inte i namesapce System.Windows.Forms, så vi kan rättmätigt använda det i BusinessLaryer, Controler och till och med moduler.
Och det är mycket smidigt att använda, du behöver bara fokusera på följande två metoder:
1. Skicka: Skickar en uppdateringsförfrågan om gränssnittet till huvudtråden och blockerar den aktuella tråden tills den returnerar.
2. Post: Skickar en uppdateringsförfrågan om gränssnittet till huvudtråden utan att blockera den aktuella tråden.
Faktum är att de alla är samma metod, förutom att sändning är synkron och efterhand är asynkron
Före Form1-form = ny Form1() var SynchronizationContext-objektet tomt, och när Form1-formuläret instansierades lades SynchronizationContext-objektet till denna tråd. Så svaret är att när Control-objektet skapas, SynchronizationContext-objektet skapas och kopplas också till tråden. Allt detta när jag använder formen InitializeComponent(); När detta är gjort kan den få ett objekt som inte är NULL
Slutligen, skillnaden mellan Sendt()- och Post()-metoderna i SynchronizationContext:
Send() implementeras genom att helt enkelt anropa delegaten i den aktuella tråden (synkront anrop). Det vill säga, UI-tråden anropas direkt på undertråden för att exekveras, och subtråden fortsätter att köras efter att UI-tråden är klar.
Post() implementeras genom att anropa en delegat i trådpoolen (asynkront anrop). Detta beror på att subtråden hittar en tråd från trådpoolen för att justera UI-tråden, och subtråden kommer direkt att köra sin egen kod utan att vänta på att UI-tråden ska bli klar. Testkod:
Utfall:
UI:s huvudtråd: 1 Tråd: 5 SynchContext:1
Sammanfattning:Objektet SynchronizationContext i UI-tråden, oavsett om det anropas i huvudtråden eller i tråden, kommer att köras på huvudtråden, så när det är mycket tidskrävande kod kommer det att göra att UI-gränssnittet fryser eller låtsas dö!
I själva verketUI-tråden använder inte klassen SynchronizationContext, utan WindowsFormsSynchronizationContextDen här Dongdong.
System.Threading.SynchronizationContext-källkod:
WindowsFormsSynchronizationContext-källkod:
|