C# BackgroundWorker使用總結

查詢了一下MSDN文檔,其中微軟就BackgroundWorker類的功能有這麼一個描述(英文的,根據我的理解翻譯):BackgroundWorker類容許您在單獨的線程上執行某個可能致使用戶界面(UI)中止響應的耗時操做(好比文件下載數據庫事務等),而且想要一個響應式的UI來反應當前耗時操做的進度。 
能夠看的出來,BackgroundWorker組件提供了一種執行異步操做(後臺線程)的同時,而且還能妥妥的顯示操做進度的解決方案。因而乎,我便深刻的瞭解了一下BackgroundWorker類。針對BackgroundWorker類的部分重要屬性和方法進行了一次總結。 數據庫

一、屬性:

  • WorkerReportsProgress 
    bool類型,指示BackgroundWorker是否能夠報告進度更新。當該屬性值爲True是,將能夠成功調用ReportProgress方法,不然將引起InvalidOperationException異常。 用法:
private BackgroundWorker bgWorker = new BackgroundWorker();
bgWorker.WorkerReportsProgress = true;
  • WorkerSupportsCancellation 
    bool類型,指示BackgroundWorker是否支持異步取消操做。當該屬性值爲True是,將能夠成功調用CancelAsync方法,不然將引起InvalidOperationException異常。 用法:
bgWorker.WorkerSupportsCancellation = true;
  • CancellationPending 
    bool類型,指示應用程序是否已請求取消後臺操做。此屬性一般放在用戶執行的異步操做內部,用來判斷用戶是否取消執行異步操做。當執行BackgroundWorker.CancelAsync()方法時,該屬性值將變爲True。 用法:
//在DoWork中鍵入以下代碼
for (int i = 0; i <= 100; i++)
{
    if (bgWorker.CancellationPending)
    {
        e.Cancel = true;
        return;
    }
    else
    {
        bgWorker.ReportProgress(i,"Working");
        System.Threading.Thread.Sleep(10);
    }
}
  • IsBusy 
    bool類型,指示BackgroundWorker是否正在執行一個異步操做。此屬性一般放在BackgroundWorker.RunWorkerAsync()方法以前,避免屢次調用RunWorkerAsync()方法引起異常。當執行BackgroundWorker.RunWorkerAsync()方法是,該屬性值將變爲True。
//防止重複執行異步操做引起錯誤
if (bgWorker.IsBusy)
    return;
bgWorker.RunWorkerAsync();

 

二、方法:

  • RunWorkerAsync() 
    開始執行一個後臺操做。調用該方法後,將觸發BackgroundWorker.DoWork事件,並以異步的方式執行DoWork事件中的代碼。 
    該方法還有一個帶參數的重載方法:RunWorkerAsync(Object)。該方法容許傳遞一個Object類型的參數到後臺操做中,而且能夠經過DoWork事件的DoWorkEventArgs.Argument屬性將該參數提取出來。 
    注:當BackgroundWorker的IsBusy屬性爲True時,調用該方法將引起InvalidOperationException異常。
//在啓動異步操做的地方鍵入代碼
bgWorker.RunWorkerAsync("hello");
  • ReportProgress(Int percentProgress) 
    報告操做進度。調用該方法後,將觸發BackgroundWorker. ProgressChanged事件。另外,該方法包含了一個int類型的參數percentProgress,用來表示當前異步操做所執行的進度百分比。 
    該方法還有一個重載方法:ReportProgress(Int percentProgress, Object userState)。容許傳遞一個Object類型的狀態對象到 ProgressChanged事件中,而且能夠經過ProgressChanged事件的ProgressChangedEventArgs.UserState屬性取得參數值。 
    注:調用該方法以前需確保WorkerReportsProgress屬性值爲True,不然將引起InvalidOperationException異常。 
    用法:
for (int i = 0; i <= 100; i++)
{
    //向ProgressChanged報告進度
    bgWorker.ReportProgress(i,"Working");
    System.Threading.Thread.Sleep(10);
}
  • CancelAsync() 
    請求取消當前正在執行的異步操做。調用該方法將使BackgroundWorker.CancellationPending屬性設置爲True。 
    但須要注意的是,並不是每次調用CancelAsync()都能確保異步操做,CancelAsync()一般不適用於取消一個緊密執行的操做,更適用於在循環體中執行。 
    用法:
//在須要執行取消操做的地方鍵入如下代碼
bgWorker.CancelAsync();

 

三、事件:

  • DoWork 
    用於承載異步操做。當調用BackgroundWorker.RunWorkerAsync()時觸發。 
    須要注意的是,因爲DoWork事件內部的代碼運行在非UI線程之上,因此在DoWork事件內部應避免於用戶界面交互,而於用戶界面交互的操做應放置在ProgressChanged和RunWorkerCompleted事件中。異步

  • ProgressChanged 
    當調用BackgroundWorker.ReportProgress(int percentProgress)方式時觸發該事件。 
    該事件的ProgressChangedEventArgs.ProgressPercentage屬性能夠接收來自ReportProgress方法傳遞的percentProgress參數值,ProgressChangedEventArgs.UserState屬性能夠接收來自ReportProgress方法傳遞的userState參數。this

  • RunWorkerCompleted 
    異步操做完成或取消時執行的操做,當調用DoWork事件執行完成時觸發。 
    該事件的RunWorkerCompletedEventArgs參數包含三個經常使用的屬性Error,Cancelled,Result。其中,Error表示在執行異步操做期間發生的錯誤;Cancelled用於判斷用戶是否取消了異步操做;Result屬性接收來自DoWork事件的DoWorkEventArgs參數的Result屬性值,可用於傳遞異步操做的執行結果。spa

四、附源代碼:

前臺線程

這裏寫圖片描述

後臺翻譯

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 PrograssBar
{
    public partial class PrograssBarUseBackgroundWorker : Form
    {

        private BackgroundWorker bgWorker = new BackgroundWorker();

        public PrograssBarUseBackgroundWorker()
        {
            InitializeComponent();
            InitializeBackgroundWorker();
        }

        private void InitializeBackgroundWorker()
        {
            bgWorker.WorkerReportsProgress = true;
            bgWorker.WorkerSupportsCancellation = true;
            bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
            bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgessChanged);
            bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_WorkerCompleted);
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (bgWorker.IsBusy)
                return;
            this.progressBar1.Maximum = 100;
            this.btnStart.Enabled = false;
            this.btnStop.Enabled = true;
            bgWorker.RunWorkerAsync("hello");
        }

        public void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i <= 100; i++)
            {
                if (bgWorker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                else
                {
                    bgWorker.ReportProgress(i,"Working");
                    System.Threading.Thread.Sleep(10);
                }
            }
        }

        public void bgWorker_ProgessChanged(object sender, ProgressChangedEventArgs e)
        {
            //string state = (string)e.UserState;//接收ReportProgress方法傳遞過來的userState
            this.progressBar1.Value = e.ProgressPercentage;
            this.label1.Text = "處理進度:" + Convert.ToString(e.ProgressPercentage) + "%";
        }

        public void bgWorker_WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Error!=null)
            {
                MessageBox.Show(e.Error.ToString());
                return;
            }
            if (!e.Cancelled)
                this.label1.Text = "處理完畢!";
            else
                this.label1.Text = "處理終止!";

        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            this.btnStart.Enabled = true;
            this.btnStop.Enabled = false;
            bgWorker.CancelAsync();
        }
    }
}

運行結果:code

這裏寫圖片描述

相關文章
相關標籤/搜索