BackgroundWorker與線程使用


  在一個程序中,一些耗時的操作,在長時間運行時可能會導致用戶界面 (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


免責聲明!

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



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