C#中Invoke的用法
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
在多線程編程中,我們經(jīng)常要在工作線程中去更新界面顯示,而在多線程中直接調(diào)用界面控件的方法是錯誤的做法,Invoke 和 BeginInvoke 就是為了解決這個問題而出現(xiàn)的,使你在多線程中安全的更新界面顯示。 Framework框架的WinForm構(gòu)建GUI程序界面時,如果要在控件的事件響應(yīng)函數(shù)中改變控件的狀態(tài),例如:某個按鈕上的文本原先叫“打開”,單擊之后按鈕上的文本顯示“關(guān)閉”,初學(xué)者往往會想當(dāng)然地這么寫: void ButtonOnClick(object sender,EventArgs e) { button.Text="關(guān)閉"; } 這樣的寫法運行程序之后,可能會觸發(fā)異常,異常信息大致是“不能從不是創(chuàng)建該控件的線程調(diào)用它”。注意這里是“可能”,并不一定會觸發(fā)該種異常。造 成這種異常的原因在于,控件是在主線程中創(chuàng)建的(比如this.Controls.Add(...);),進入控件的事件響應(yīng)函數(shù)時,是在控件所在的線 程,并不是主線程。在控件的事件響應(yīng)函數(shù)中改變控件的狀態(tài),可能與主線程發(fā)生線程沖突。如果主線程正在重繪控件外觀,此時在別的線程改變控件外觀,就會造 成畫面混亂。不過這樣的情況并不總會發(fā)生,如果主線程此時在重繪別的控件,就可能逃過一劫,這樣的寫法可以正常通過,沒有觸發(fā)異常。 正確的寫法是在控件響應(yīng)函數(shù)中調(diào)用控件的Invoke方法(其實如果大家以前用過C++ Builder的話,也會找到類似Invoke那樣的激活到主線程的函數(shù))。Invoke方法會順著控件樹向上搜索,直到找到創(chuàng)建控件的那個線程(通常是主線程),然后進入那個線程改變控件的外觀,確保不發(fā)生線程沖突。 而所謂的“一面響應(yīng)操作,一面添加節(jié)點”永遠只能是相對的,使 UI 線程的負擔(dān)不至于太大而已,因為界面的正確更新始終要通過 UI 線程去做,我們要做的事情是在工作線程中包攬大部分的運算,而將對純粹的界面更新放到 UI 線程中去做,這樣也就達到了減輕 UI 線程負擔(dān)的目的了。 using System.Threading; 該文章在 2021/1/29 21:18:10 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |