在一個程序中,一些耗時的操做,在長時間運行時可能會致使用戶界面 (UI) 處於中止響應狀態,用戶在這操做期間沒法進行其餘的操做,爲了避免使UI層處於中止響應狀態,須要將這些耗時的操做,設置爲後臺線程,而且在UI層能夠展現後臺操做的進度,比較經常使用的方法有使用線程以及BackgroundWorker類。this
一、線程方法spa
當咱們要在前太展現後臺的操做進程時,是不容許跨線程訪問控件。此時須要取消控件的跨線程訪問,在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();code
當點擊開始按鈕時進度條就會顯示進度component
二、使用BackgroundWorkerorm
BackgroundWorker 類容許在單獨的專用線程上運行操做,使用BackgroundWorker 須要引用System.ComponentModelblog
BackgroundWorker 有三個重要的事件進程
this.bgWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
this.bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
this.bgWorker.ProgressChanged +=new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);事件
DoWork(),將須要處理的後臺操做放入DoWork()中io
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