后台線程更新界面的巧妙方法


在單機版程序的設計中,對於需要較長時間運行的操作,一般都通過后台線程來完成。如果直接用 UI 線程(在 click 事件中) 運行,則 UI 界面長時間得不到機會重新繪制,會造成程序假死的現象(俗稱“翻白眼”)。

 

后台線程更新界面有一些注意事項:

1. 后台線程一般不能直接操作界面控件,需要調用 invoke 之類的函數;

2. 后台線程更新界面的頻次不能太慢,太慢則也容易讓用戶覺得程序“死掉了”;

3. 后台線程更新界面不能太快,一來界面更新太快人眼看不清,容易讓人覺得程序好像失控了,在胡亂顯示一些亂碼;二來,界面更新太快,也會影響整個操作的完成速度,更新界面也是需要 CPU 的。我們知道,電影每秒是 24幀,也就是說,每秒更新畫面 24 次,是可以讓人覺得很流暢的,每秒更新超過 24 次是不必要的。

 

如果只有問題1 ,則還比較好處理。網上很多講述 invoke 之類的函數。雖然麻煩,也還算在可控范圍。

對於問題2/3, 則不容易處理。比如,我的程序是批量復制文件,在我的開發計算機上經過測試,每復制 10 個文件,更新一下界面,看起來比較好。程序就這么寫了。

交付給用戶之后,如果用戶的計算機比我的計算機快了很多,或者慢了很多,則運行界面效果還是不理想:不是更新太快、就是更新太慢。

 

解決辦法是:

更新用戶界面,采用定時器 timer ,取名 UpdateUiTimer。后台線程運行過程中,把運行狀態(百分比、狀態提示詳細字符串、主要步驟字符串)放入全局變量中,UpdateUiTimer 來讀取全局變量並顯示。定時器運行間隔,可以設置成每秒 2 –5 次(我的經驗值)。invoke 之類的函數就不要調用了。這樣可以解決問題。

 

全局變量類設計,可以為這樣的形式:

public class GlobalVars
{

    public static int RunningPercent;

    public static string RunningMainStepStatus;

    public static string RunningDetailStepStatus;

}

這里有幾個注意事項:

a. 多線程對同一個變量的讀寫,如果不加特別控制,是有一點緩存、延遲的。也就是說,一個線程對變量的更改,並不一定會被另一個線程讀到。舉例來說,工作線程先更新完成進度為 5%, 然后更新為 10%,這時候 timer 去讀取進度,有可能讀到 5%,下次才能讀到 10%。不過這點對我們的顯示程序邏輯,不構成多大影響。

b. 后台線程運行的時候,最好把界面 disable,不然用戶可能點擊兩次按鈕,或者在后台在運行的時候,做別的事情,有可能會互相影響。

 

-------------轉載請注明來源:http://www.cnblogs.com/jacklondon

-------------歡迎大家下載試用折桂單點登錄系統, http://zheguisoft.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM