轉自:http://www.cnblogs.com/zzy0471/archive/2010/12/12/1903602.html
在WinForm開發中,在處理大量數據時不免會有耗時較長的操作,如果將這些操作放在主線程里,軟件界面會有較長時間的“無響應”,降低了用戶體驗,常用的解決方式是加上進度條。
實現思路
使用BackgroundWorker(已經封裝好的線程工具)控件在后台線程執行費時的操作,在主線程中打開一個進度條窗體顯示進度。
實現步驟
第0步:創建一個具有進度條的窗體,以顯示進度
新建窗體ProcessForm,設置屬性FormBorderStyle為None,添加一個ProcessBar控件,如下圖所示:
PrcessBar的Style屬性設置為MarQuee。在ProcessForm添加如下公共屬性:
1234567891011121314151617181920212223/// <summary>/// 設置提示信息/// </summary>publicstringMessageInfo{set{this.labelInfor.Text = value; }}/// <summary>/// 設置進度條顯示值/// </summary>publicintProcessValue{set{this.progressBar1.Value = value; }}/// <summary>/// 設置進度條樣式/// </summary>publicProgressBarStyle ProcessStyle{set{this.progressBar1.Style = value; }}
第1步:創建進度條管理類ProcessOperator
在該類中添加如下字段:
12privateBackgroundWorker _backgroundWorker;//后台線程privateProcessForm _processForm;//進度條窗體添加如下公共屬性、方法和事件:
123456789101112131415161718192021222324252627282930#region 公共方法、屬性、事件/// <summary>/// 后台執行的操作/// </summary>publicAction BackgroundWork {get;set; }/// <summary>/// 設置進度條顯示的提示信息/// </summary>publicstringMessageInfo{set{ _processForm.MessageInfo = value; }}/// <summary>/// 后台任務執行完畢后事件/// </summary>publiceventEventHandler<EventArgs> BackgroundWorkerCompleted;/// <summary>/// 開始執行/// </summary>publicvoidStart(){_backgroundWorker.RunWorkerAsync();_processForm.ShowDialog();}#endregion其中,屬性BackgroundWork可以指向一個無參數的方法,這里(客戶端代碼)用來指向要在后台執行的費時操作方法,在_backgroundWorker的事件DoWork中調用該委托指向的方法
12345678//后台執行的操作privatevoid_backgroundWorker_DoWork(objectsender, DoWorkEventArgs e){if(BackgroundWork !=null){BackgroundWork();}}public void Start() 為啟動進度條的方法,調用該方法后,會在后台線程(_backgroundWorker.RunWorkerAsync(); )中執行費時操作(DoWork事件中的委托指向的方法)。同時,_processForm.ShowDialog()方法負責打開進度條窗體。
當后台方法執行完畢后,會觸發backgroundWorker的RunWorkerCompleted事件,在該事件中關閉進度條窗體
123456789101112//操作進行完畢后關閉進度條窗體privatevoid_backgroundWorker_RunWorkerCompleted(objectsender, RunWorkerCompletedEventArgs e){if(_processForm.Visible ==true){_processForm.Close();}if(this.BackgroundWorkerCompleted !=null){this.BackgroundWorkerCompleted(null,null);}}以下是完整的ProcessOperator類代碼:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485/** author:Joey Zhao* date:2010-11-30* describe:進度條,該類可以在后台線程處理一些費時操作,並顯示進度條,進度條並未真實顯示數據進度* 僅僅是告訴用戶程序還活着,有待加強。使用方法:* 1, 實例化一個ProcessOperator對象;* 2,賦值BackgroundWork(類型為一個無參數無返回值的委托)屬性為要在后台執行的方法(無參數無返回值的方法)* 3,調用Start方法開始執行* 4, 在事件BackgroundWorkerCompleted中執行后台任務完成后的操作*/usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.ComponentModel;namespaceSasp.Client.PublicUnits.Process{publicclassProcessOperator{privateBackgroundWorker _backgroundWorker;//后台線程privateProcessForm _processForm;//進度條窗體publicProcessOperator(){_backgroundWorker =newBackgroundWorker();_processForm =newProcessForm();_backgroundWorker.DoWork +=newDoWorkEventHandler(_backgroundWorker_DoWork);_backgroundWorker.RunWorkerCompleted +=newRunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);}//操作進行完畢后關閉進度條窗體privatevoid_backgroundWorker_RunWorkerCompleted(objectsender, RunWorkerCompletedEventArgs e){if(_processForm.Visible ==true){_processForm.Close();}if(this.BackgroundWorkerCompleted !=null){this.BackgroundWorkerCompleted(null,null);}}//后台執行的操作privatevoid_backgroundWorker_DoWork(objectsender, DoWorkEventArgs e){if(BackgroundWork !=null){BackgroundWork();}}#region 公共方法、屬性、事件/// <summary>/// 后台執行的操作/// </summary>publicAction BackgroundWork {get;set; }/// <summary>/// 設置進度條顯示的提示信息/// </summary>publicstringMessageInfo{set{ _processForm.MessageInfo = value; }}/// <summary>/// 后台任務執行完畢后事件/// </summary>publiceventEventHandler<EventArgs> BackgroundWorkerCompleted;/// <summary>/// 開始執行/// </summary>publicvoidStart(){_backgroundWorker.RunWorkerAsync();_processForm.ShowDialog();}#endregion}}第2步:客戶端代碼調用
1234PercentProcessOperator p =newPercentProcessOperator();p.BackgroundWork =this.LoadData;p.BackgroundWorkerCompleted +=newEventHandler<EventArgs>(p_BackgroundWorkerCompleted);p.Start();擴展:實時報告后台處理進度
將_backgroundWorker的屬性WorkerReportsProgress設置為ture;這樣就可以添加backgroundWorker的ProgressChanged事件了(該事件在調用方法_backgroundWorker.ReportProgress(int p)時觸發。
123456//顯示進度privatevoid_backgroundWorker_ProgressChanged(objectsender, ProgressChangedEventArgs e){_processForm.MessageInfo ="已完成:"+e.ProgressPercentage.ToString()+"%";_processForm.ProcessValue = e.ProgressPercentage;}_backgroundWorker.ReportProgress(int p)方法應該是在后台執行操作中調用,只有后台執行的操作才知道自己的完成進度。可以使用一個委托參數,客戶端代碼調用該委托設置進度,而該委托指向的方法設置為_backgroundWorker.ReportProgress(int p)即可。以下代碼是帶有進度預報的實現:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113/** author:Joey Zhao* date:2010-12-1* describe:帶百分比的進度條,使用方法:* 1, 實例化一個ProcessOperator對象;* 2,賦值BackgroundWork(類型為一個參數,無返回值的委托,其中參數是一個具有一個int類型參數無返回值的委托,用來預報進度)屬性為要在后台執行的方法,詳見TestForm中的示例* 3,調用Start方法開始執行* 4, 在事件BackgroundWorkerCompleted中執行后台任務完成后的操作*/usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.ComponentModel;namespaceSasp.Client.PublicUnits.Process{publicclassPercentProcessOperator{privateBackgroundWorker _backgroundWorker;//后台線程privateProcessForm _processForm;//進度條窗體publicPercentProcessOperator(){_processForm =newProcessForm();_processForm.ProcessStyle = System.Windows.Forms.ProgressBarStyle.Continuous;_backgroundWorker =newBackgroundWorker();_backgroundWorker.WorkerReportsProgress =true;_backgroundWorker.DoWork +=newDoWorkEventHandler(_backgroundWorker_DoWork);_backgroundWorker.RunWorkerCompleted +=newRunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);_backgroundWorker.ProgressChanged +=newProgressChangedEventHandler(_backgroundWorker_ProgressChanged);}//顯示進度privatevoid_backgroundWorker_ProgressChanged(objectsender, ProgressChangedEventArgs e){_processForm.MessageInfo ="已完成:"+e.ProgressPercentage.ToString()+"%";_processForm.ProcessValue = e.ProgressPercentage;}//操作進行完畢后關閉進度條窗體privatevoid_backgroundWorker_RunWorkerCompleted(objectsender, RunWorkerCompletedEventArgs e){if(_processForm.Visible ==true){_processForm.Close();}if(this.BackgroundWorkerCompleted !=null){this.BackgroundWorkerCompleted(null,null);}}//后台執行的操作privatevoid_backgroundWorker_DoWork(objectsender, DoWorkEventArgs e){if(BackgroundWork !=null){BackgroundWork(this.ReportPercent);}}#region 公共方法、屬性、事件/// <summary>/// <para>后台執行的操作,參數為一個參數為int型的委托;/// 在客戶端要執行的后台方法中可以使用Action<int>預報完成進度,如:/// <example>/// <code>/// PercentProcessOperator o = new PercentProcessOperator();/// o.BackgroundWork = this.DoWord;////// private void DoWork(Action<int> Report)/// {/// Report(0);/// //do soming;/// Report(10);/// //do soming;/// Report(50);/// //do soming/// Report(100);/// }/// </code>/// </example></para>/// </summary>publicAction<Action<int>> BackgroundWork {get;set; }/// <summary>/// 后台任務執行完畢后事件/// </summary>publiceventEventHandler<EventArgs> BackgroundWorkerCompleted;/// <summary>/// 開始執行/// </summary>publicvoidStart(){_backgroundWorker.RunWorkerAsync();_processForm.ShowDialog();}#endregion//報告完成百分比privatevoidReportPercent(inti){if(i >=0 && i<=100){_backgroundWorker.ReportProgress(i);}}}}
1
還是把Demo傳來了,原來的代碼找不到了,今天現寫了個例子,O(∩_∩)O哈哈~ 點擊下載

