天天看點

BackgroundWorker 實作的多線程操作

BackgroundWorker元件介紹

BackgroundWorker是·net裡用來執行多線程任務的控件,它允許程式設計者在一個單獨的線程上執行一些操作。
           

常用方法

  1. RunWorkerAsync 開始執行背景操作。引發 DoWork 事件
  2. CancelAsync 請求取消挂起的背景操作。注意:這個方法是将 CancellationPending 屬性設定為 true,并不會終止背景操作。在背景操作中要檢查CancellationPending 屬性,來決定是否要繼續執行耗時的操作。
  3. ReportProgress引發 ProgressChanged 事件。

常用屬性

  1. CancellationPending 訓示應用程式是否已請求取消背景操作。隻讀屬性,預設為 false,當執行了 CancelAsync 方法後,值為 true。
  2. WorkerSupportsCancellation訓示是否支援異步取消。要執行 CancelAsync 方法,需要先設定該屬性為 true。
  3. WorkerReportsProgress訓示是否能報告進度。要執行 ReportProgress 方法,需要先設定該屬性為 true。
注意:
  • 在 DoWork 事件處理程式中不操作任何使用者界面對象。而應該通過 ProgressChanged 和RunWorkerCompleted 事件與使用者界面進行通信。
  • 如果想在 DoWork 事件處理程式中和使用者界面的控件通信,可在用 ReportProgress 方法。ReportProgress(int percentProgress, object userState),可以傳遞一個對象。ProgressChanged 事件可以從參數ProgressChangedEventArgs 類的UserState 屬性得到這個資訊對象。這個事件也可以實作進度條功能,把任務的進度實時呈現給使用者。
  • 簡單的程式用BackgroundWorker 比 Thread 友善,Thread中和使用者界面上的控件通信比較麻煩,需要用委托來調用控件的 Invoke 或BeginInvoke 方法,沒有 BackgroundWorker 友善。

執行個體

public partial class Analyse : Form
 {
	    public Analyse()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;  //線程間操作無效: 從不是建立控件“XXX”的線程通路它。
        }

		/// <summary>
        /// Analyse
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Analyse_btn_Click(object sender, EventArgs e)
        {
            try
            {
                // 資料分析
                if (!bgWorker_Process.IsBusy)
                {
                    AnalyseResults = new List<AnalyseResultMdl>();
                    this.bgWorker_Process = new BackgroundWorker()  //new一個新的,避免重複添加相同和其他無用DoWork,也可以不用new
                    {
                        WorkerReportsProgress = true  //能否報告進度更新
                    };
                    this.bgWorker_Process.DoWork += new DoWorkEventHandler(Analyse_DoWork);
                    this.bgWorker_Process.ProgressChanged += new ProgressChangedEventHandler(bgWorker_Process_ProgressChanged);
                    this.bgWorker_Process.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Process_RunWorkerCompleted);
                    this.bgWorker_Process.RunWorkerAsync(); // 運作 backgroundWorker 元件
                }
                else
                {
                    MessageBox.Show($"等待其他操作完成再執行...");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"分析出錯:{ex}");
            }
        }

		/// <summary>
        /// Analyse_DoWork
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Analyse_DoWork(object sender, EventArgs e)
        {
        	int intPercentage=1;
			foreach (var item in itemList)
			{
				bgWorker_Process.ReportProgress(Convert.ToInt32(Math.Floor(Convert.ToDouble(intPercentage * 100 / BaseDataList.Count()))));   // 觸發bgWorker_Process.ProgressChanged事件
				// 耗時操作
				// 。。。
				intPercentage++;
			}
        }

		/// <summary>
        /// 進度變化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		private void bgWorker_Process_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;  //progressBar1 進度條控件
        }
        
        /// <summary>
        /// 程式執行完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bgWorker_Process_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
            }
            else
            {
                this.bgWorker_Process.Dispose();
            }
        }
 }

           
END