背景介紹:
在做程序的進程中,我們極可能遇到這樣的情況:當我們履行1個比較耗時的操作,即界面加載數據量略大的時,在該操作未完成之前再去操作界面,就會出現停止響應的情況,這稱為界面假死狀態,那1個小圓圈轉呀轉的,想必大家看著就頭疼。固然這是1個非常影響用戶體驗度的地方。
怎樣做出1個能夠及時響應的用戶界面呢?多線程操作。
引入BackgroundWorker組件:
BackgroundWorker是?net里用來履行多線程任務的控件,它允許編程者在1個單獨的線程上履行1些操作。
經常使用方法
1.RunWorkerAsync 開始履行后臺操作。引發 DoWork 事件
2.CancelAsync 要求取消掛起的后臺操作。
注意:這個方法是將 CancellationPending 屬性設置為 true,其實不會終止后臺操作。在后臺操作中要檢查 CancellationPending 屬性,來決定是不是要繼續履行耗時的操作。
3.ReportProgress 引發 ProgressChanged 事件。
經常使用屬性
1.CancellationPending 唆使利用程序是不是已要求取消后臺操作。只讀屬性,默許為 false,當履行了 CancelAsync 方法后,值為 true。
2.WorkerSupportsCancellation 唆使是不是支持異步取消。要履行 CancelAsync 方法,需要先設置該屬性為 true。
3.WorkerReportsProgress 唆使是不是能報告進度。要履行 ReportProgress 方法,需要先設置該屬性為 true。
經常使用事件
1.DoWork 調用 RunWorkerAsync 方法時產生。
2.RunWorkerCompleted 后臺操作已完成、被取消或引發異常時產生。
3.ProgressChanged 調用 ReportProgress 方法時產生。
注意:在 DoWork 事件處理程序中不操作任何用戶界面對象。而應當通過 ProgressChanged 和RunWorkerCompleted 事件與用戶界面進行通訊。
如果想在 DoWork 事件處理程序中和用戶界面的控件通訊,可在用 ReportProgress 方法。ReportProgress(int percentProgress, object userState),可以傳遞1個對象。
ProgressChanged 事件可以從參數ProgressChangedEventArgs 類的UserState 屬性得到這個信息對象。這個事件也能夠實現進度條功能,把任務的進度實時顯現給用戶。
簡單的程序用BackgroundWorker 比 Thread 方便,Thread中和用戶界面上的控件通訊比較麻煩,需要用拜托來調用控件的 Invoke 或BeginInvoke 方法,沒有 BackgroundWorker 方便。
BackgroundWorker Demo
總結:
使用backgroundWorker實現多線程大致的步驟是:
1、 綁定線程,設置屬性
2、調用BackgroundWorker的RunWorkerAsync方法(可以傳遞參數),它將調用DoWork事件
3、聲明DoWork事件的拜托方法,在后臺履行耗時的操作
4、在耗時操作中判斷CancellationPending屬性,如果為false則退出
5、如果要向用戶界面發送信息,則調用BackgroundWorker的ReportProgress方法,它將調用ProgressChanged事件(可以將改變通過object類型傳遞)
6、在ProgressChanged事件的響應代碼中將改變顯現給用戶,類似進度條。
7、如果需要取消耗時操作,則調用BackgroundWorker的CancelAsync方法,需要和步驟31起使用
總的來講就是用backgroundWorker組件來新建1個線程,把耗時的部份放到這個線程中在后臺進行處理。這樣就不會影響界面的正常使用。舉個通俗的例子,在我們打開1個網頁的時候,先加載完的總是文字,然后圖片在漸漸出現。這就是線程的利用,網頁打開的時候先顯現出文字,供用戶閱讀,然后把加載圖片放到1個單獨的線程中,異步的在后臺履行,履行終了后把圖片顯現出來。
這樣就避免了1打開界面就加載大量信息,而釀成的界面假死狀態,大大提高了用戶體驗度。
線程處理這塊不熟,希望大家指導。