天天看點

C#學習筆記之BackGroundWorder

C#學習筆記之BackGroundWorder
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BackGroundWorder元件控件
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        /// <summary>
        /// BackGroundWorker是.NET裡用來執行多線程的控件,它允許程式員在單獨的一個線程裡
        /// 執行一些操作。耗時的操作(比如下載下傳和資料庫事務)在長時間運作時可能會導緻使用者界面
        /// 始終處于“未響應”狀态。
        /// 
        /// 該控件有三個事件:DoWork、ProgressChanged、RunWorkerCompleted。
        /// 在程式中調用 RunWorkerAsync() 方法則會啟動 DoWork 事件;當在事件處理過程中,調用
        /// ReportProgress() 方法則會啟動 ProgressChanged 事件;而當 DoWork 事件處理完成時
        /// 則會觸發 RunWorkerCompleted 事件。
        /// 
        /// 注意:如果在 DoWork 事件中操作任何使用者界面對象,界面仍然會出現“未響應”;應該在事件
        /// ProgressChanged 和 RunWorkerCompleted 中和窗體進行通信。
        /// </summary>


        // 在程式中調用 RunWorkerAsync() 将會觸發該事件:
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // sender:表示觸發該事件的控件對象
            // e 有三個屬性:Cancel、Argument、Result

            // 1、Cancel:DoWork 事件中的代碼應定期檢查 CancellationPending 屬性值,并在該值
            // 為 true 時終止操作,true表示應用程式已經請求取消背景操作,此時 Cancel 應設定
            // 為 true,同時 RunWorkerCompleted 事件處理程式中的Cancelled也變為 true。
            if (backgroundWorker1.CancellationPending == true)
            {
                e.Cancel = true;
                return;
            }

            // 2、Argument:觸發 DoWork 事件的方法 RunWorkerAsync() 有兩種重載,一種無參,
            // 另一種有一個object類型的參數;當調用有參方法時,e 的 Argument 屬性将會指向
            // 這個參數。
            string str = e.Argument.ToString(); // 擷取 RunWorkerAsync() 傳遞過來的值
            for (int i = 1; i <= 100; i++)
            {
                string strr = "第" + i + "句:" + str;

                // 觸發 ProgressChanged 事件
                backgroundWorker1.ReportProgress(i, strr);

                if (i == 50)
                {
                    // 此方法隻是請求取消,此處并沒有取消。
                    backgroundWorker1.CancelAsync();
                    MessageBox.Show("請求取消背景操作!");

                    if (backgroundWorker1.CancellationPending == true)
                    {
                        e.Cancel = true;
                        MessageBox.Show("背景程式中斷!");
                        return;
                    }
                }
                Thread.Sleep(200);
            }

            // 3、Result:此處将Result設定成什麼,RunWorkerCompleted 事件中的Result就是什麼。
            e.Result = "完美結束!";
        }

        // 在 DoWork 事件中調用 ReportProgress() 方法就會觸發該事件。
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // ReportProgress() 有兩種重載:
            // void ReportProgress(int persentProgress);
            // void ReportProgress(int persentProgress, object userState);

            // ReportProgress() 的第一個參數一般用來報告該背景操作完成的進度,可以通過 
            // ProgressChanged 事件中 e 的 ProgressPersentage 屬性來擷取。如果還想傳遞
            // 更多的參數,可以使用參數 userState,可以通過事件 e 的 UserState屬性來擷取。

            progressBar1.Value = e.ProgressPercentage;
            label1.Text = e.UserState.ToString();
        }

        // 當 DoWork 事件處理程式結束之後将會觸發此事件。
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show("背景程式出錯:" + e.Error.Message.ToString());
            }
            else if (e.Cancelled)
            {
                MessageBox.Show("背景程式被終止!");
            }
            else
            {
                MessageBox.Show("背景程式運作結束!\r\n" + e.Result);
            }
        }

        // 啟動背景程式
        private void button1_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy)
            {
                MessageBox.Show("背景程式正在執行!");
            }
            else
            {
                // 啟動背景程式
                backgroundWorker1.RunWorkerAsync("Hello World");
            }

            backgroundWorker1.WorkerReportsProgress = true;        // 設定支援報告進度更新
            backgroundWorker1.WorkerSupportsCancellation = true;   // 設定支援取消背景操作    
        }
    }
}

           

繼續閱讀