Прочетох много въвеждащи статии за това как да се обнови основният интерфейс във фоновата нишка, и повечето от тях използват Control.Invoke и Control.BeginInvoke. Това са добри решения, но има два проблема:
1. Трябва да се позовавате на System.Windows.Forms и след това да използвате System.Windows.Forms
2. Структурата на кода е сравнително хаотична. (Всъщност, това също е причинено от #1)
Microsoft предлага още едно по-елегантно решение – System.Threading. SynchronizationContext。 Както виждате, не е в namesapce System.Windows.Forms, така че можем справедливо да го използваме в BusinessLaryer, Controler и дори модули.
И е много удобен за използване, трябва да се съсредоточите само върху следните два метода:
1. Изпращане: Изпраща заявка за обновяване на интерфейса към основната нишка, блокирайки текущата нишка, докато не се върне.
2. Пост: Изпраща заявка за обновяване на интерфейса към основната нишка без блокиране на текущата нишка.
Всъщност всички са един и същ метод, с изключение на това, че изпращането е синхронно, а пост е асинхронно
Преди Form1 form = new Form1(), обектът SynchronizationContext беше празен, а когато формата Form1 се създаваше, обектът SynchronizationContext се добавяше към тази нишка. Отговорът е, че когато се създаде Control обект, обектът SynchronizationContext също се създава и прикрепя към нишката. Всичко това при използване на формата InitializeComponent(); След като това се направи, може да се получи обект, който не е NULL
Накрая, разликата между методите Sendt() и Post() в SynchronizationContext:
Send() се реализира просто чрез извикване на делегата в текущата нишка (синхронно извикване). Тоест, UI нишката се извиква директно на поднишката за изпълнение и поднишката ще продължи да се изпълнява след завършване на изпълнението на UI нишката.
Post() се реализира чрез извикване на делегат в пула на нишките (асинхронно повикване). Това е така, защото поднишката ще намери нишка от пула на нишките, за да настрои UI нишката, и тя директно ще изпълни собствения си код, без да чака UI нишката да завърши. Тестов код:
Резултат:
Основна тема на интерфейса: 1 Тема: 5 SynchContext:1
Резюме:Обектът SynchronizationContext в UI нишката, независимо дали е извикан в основната нишка или в нея, ще се изпълнява върху основната нишка, така че когато има много времеемък код, това ще предизвика замръзване на интерфейса на UI или фалшива смърт!
ВсъщностUI нишката не използва класа SynchronizationContext, а WindowsFormsSynchronizationContextТози Донгдонг.
System.Threading.SynchronizationКонтекстен изходен код:
Изходен код на WindowsFormsSynchronizationContext:
|