在一個程序中,一些耗時的操作,在長時間運行時可能會導致用戶界面 (UI) 處於停止響應狀態,用戶在這操作期間無法進行其他的操作,為了不使UI層處於停止響應狀態,需要將這些耗時的操作,設置為后台線程,並且在UI層可以展示后台操作的進度,比較常用的方法有使用線程以及BackgroundWorker類。
1、線程方法
當我們要在前太展示后台的操作進程時,是不允許跨線程訪問控件。此時需要取消控件的跨線程訪問,在winform中可以設置CheckForIllegalCrossThreadCalls = false,而在wpf中不存在CheckForIllegalCrossThreadCalls 這個屬性,在這介紹一種方法,取消跨線程訪問,在wpf中有Dispatcher屬性使用委托的方法來告訴控件需要做什么。
public Action<int> proBarDel;//先定義一個委托 /// <summary> /// 取消誇線程訪問 /// </summary> /// <param name="str"></param> private void CrossThread(int i) { //取消控件誇線程訪問 proBarDel = this.GetReceive; this.pb.Dispatcher.Invoke(proBarDel, i); this.lab1.Dispatcher.Invoke(proBarDel, i); } /// <summary> /// 為控件設置內容 /// </summary> /// <param name="receiveStr"></param> public void SetValue(int receive) { pb.Value = receive; lab1.Content = receive; }
//在按鈕的點擊事件中新增一個線程
Thread th = new Thread(() => {
for (int i = 0; i <= 100; i++)
{
CrossThread(i);//將執行的進度匯報給UI層的控件
Thread.Sleep(100);
}
});
th.IsBackground = true;
th.Start();
當點擊開始按鈕時進度條就會顯示進度
2、使用BackgroundWorker
BackgroundWorker 類允許在單獨的專用線程上運行操作,使用BackgroundWorker 需要引用System.ComponentModel
BackgroundWorker 有三個重要的事件
this.bgWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
this.bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
this.bgWorker.ProgressChanged +=new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
DoWork(),將需要處理的后台操作放入DoWork()中
BackgroundWorker bgWorker = new BackgroundWorker();//創建一個BackgroundWorker
/// <summary> /// 需要處理的事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { e.Result = DoWork(bgWorker, e); } private bool DoWork(BackgroundWorker bk,DoWorkEventArgs e) { int num = (int)e.Argument;// int p = 0; for (int i = 0; i < num; i++) { if (bk.CancellationPending)//判斷是否取消后台操作 { return false; } else { p = (int)(((double)i / (double)num )* 100); bk.ReportProgress(p);//報告進度 Thread.Sleep(100); } } return true; }
ProgressChanged調用 ReportProgress 時發生
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { proBar.Value = e.ProgressPercentage;//獲得進度給進度條 this.lab1.Content = e.ProgressPercentage; }
RunWorkerCompleted 后台操作執行完成時或取消時發生
/// <summary> /// 處理完成 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { MessageBox.Show("ok"); }
在使用BackgroundWorker 報告后台的進度時需要將 WorkerReportsProgress 設置為true,否則在bk.ReportProgress(p)報告進度是會拋出異常
以上只是個人使用的總結,不是很全面,希望大家補充,有錯誤的地方希望能夠指出
在MSDN中有對BackgroundWorker的詳細的講解https://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker.aspx