1. 程式人生 > >C#元件之backgroundWorker

C#元件之backgroundWorker

這篇文章寫得很好 C# BackgroundWorker 詳解,一步一步描述很清楚

1、新增控制元件

backgroundWorker1           元件

label1、label2                    用於顯示過程和結果資訊

progressBar1                     顯示後臺處理進度

button1                              用於取消後臺操作

2、詳細程式碼

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.Threading;

namespace DemoCSDN
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            progressBar1.Maximum = 100;
            backgroundWorker1.RunWorkerAsync(100);//呼叫RunWorkerAsync方法啟動計算過程,其實這個方法可以接受一個 object 型別的引數。通過它我們就可以把任何資料傳遞給計算過程
            backgroundWorker1.WorkerReportsProgress = true;//允許我們在執行計算的過程中給UI執行緒傳送訊息
            backgroundWorker1.WorkerSupportsCancellation = true;//支援使用者取消操作
        }
        //執行計算的過程中給UI執行緒傳送訊息
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //修改進度條的顯示。
            progressBar1.Value = e.ProgressPercentage;

            //如果有更多的資訊需要傳遞,可以使用 e.UserState 傳遞一個自定義的型別。
            //這是一個 object 型別的物件,您可以通過它傳遞任何型別。
            //我們僅把當前 sum 的值通過 e.UserState 傳回,並通過顯示在視窗上。
            string message = e.UserState.ToString();
            label1.Text = message;
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bgWorker = sender as BackgroundWorker;
            int endNumber = 0;
            if (e.Argument != null)
            {
                endNumber = (int)e.Argument;
            }

            int sum = 0;
            for (int i = 0; i <= endNumber; i++)
            {
                sum += i;

                string message = "Current sum is: " + sum.ToString();
                //ReportProgress 方法把資訊傳遞給 ProcessChanged 事件處理函式。
                //第一個引數型別為 int,表示執行進度。
                //如果有更多的資訊需要傳遞,可以使用 ReportProgress 的第二個引數。
                //這裡我們給第二個引數傳進去一條訊息。
                bgWorker.ReportProgress(i, message);
                Thread.Sleep(100);
                //在操作的過程中需要檢查使用者是否取消了當前的操作。
                if (bgWorker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
            }
            //如果想要拿到 e.Result,您需要在DoWork方法中設定 e.Result屬性
            e.Result = sum;
        }
        //如果檢測到使用者點選的取消按鈕,就退出當前的計算過程。下面是點選取消按鈕時要呼叫的程式碼:
        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();
        }
        /*如果在計算過程中發生了異常該怎麼處理?有沒有辦法知道計算過程已經結束?當然要有,即便是正常的結束也需要拿到計算的結果。
         *通過這個事件我們可以進行一些運算結束後的操作,比如禁用取消按鈕,異常處理,結果顯示等。*/
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //如果使用者取消了當前操作就關閉視窗。
            if (e.Cancelled)
            {
                this.Close();
            }

            //計算已經結束,需要禁用取消按鈕。
            this.button1.Enabled = false;

            //計算過程中的異常會被抓住,在這裡可以進行處理。
            if (e.Error != null)
            {
                Type errorType = e.Error.GetType();
                switch (errorType.Name)
                {
                    case "ArgumentNullException":
                    case "MyException":
                        //do something.
                        break;
                    default:
                        //do something.
                        break;
                }
            }

            //計算結果資訊:e.Result
            //use it do something.
            label2.Text = "完成 sum:" + e.Result.ToString();
        }

    }
}

3、介面顯示