C# 后台线程编程 - BackgroundWorker

C# 后台线程编程 - BackgroundWorker

用途

Win Form程序不做特别操作是在GUI线程运行的,如果你有比较耗时的工作,将会Hold住GUI没法更新显示运行状态。
BackgroundWorker 类是你能够另起一个线程,将线程进度汇报给GUI线程,也可以从GUI线程通知这个线程终止。

技术解释

  1. WinForm开发界面时,从Toolbox选择BackgroundWorker加到Form。并修改名称(属性》Name)。在这个范例里面我改名字为backgroundWorkerCounter,因为我要让它做一个倒计数。

  2. 在其属性设置支持WorkerReportProgress和WorkerSupportsCancellation
    C# 后台线程编程 - BackgroundWorker_第1张图片

  3. 在backgroundWorker属性》事件》Asynchronous》下面3个事件的空白处双击,创建空白的事件响应方法。
    C# 后台线程编程 - BackgroundWorker_第2张图片

  4. 编程
    a. 如下图所示,后台线程的主线工作在bdw_DoWork()里面完成。这个方法里面定义了你的工作、对终止后台工作的响应,并且调用ReportProgress()方法向GUI线程报告进度。
    b. 在GUI线程你可以对实例化的bgw如此操作:
    RunWorkerAsync(): 启动一个异步线程,不会Hold住界面。如果要向后台程序传递参数,可以在方法调用里面加数据,在后台调用e.Argument获取。详见例程。
    CancelAsync(): 通知后台线程终止,实际上就是传递一个布尔标记。
    c. 在GUI线程你可以对后台事件如此响应:
    bgw_ProgressChanged(): 响应后台ReportProgress进度值变化
    bgw_RunWorkerCompleted(): 响应后台运行完毕
    C# 后台线程编程 - BackgroundWorker_第3张图片

范例代码

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.Threading;
/// 
/// 显示一个计数的范例,演示Background Worker的编程
/// 
namespace bgwCounter
{
    public partial class Form1 : Form
    {
        /// 
        /// 自动生成的Form实例化
        /// 
        public Form1()
        {
            InitializeComponent();
        }
        /// 
        /// BackgroundWorker主要工作在此,方法框架是VS自动生成的
        /// 
        /// 
        /// 
        private void backgroundWorkerCounter_DoWork(object sender, DoWorkEventArgs e)
        {
            //从输入变量获得计数起始值
            int counterStart = (int) e.Argument;
            int counter = 0;
            //循环递减到0
            for (int i = 0; i < counterStart+1; i++)
            {
                counter = counterStart - i;
                //如果倒计数过程中软件调用了backgroundWorker Cancel,则退出循环
                if(backgroundWorkerCounter.CancellationPending==true)
                {
                    e.Cancel = true;
                    break;
                }
                //每次循环等待1秒
                Thread.Sleep(1000);
                //每次循环汇报进度,此处为倒计数值,供显示
                backgroundWorkerCounter.ReportProgress(counter);
            }
        }
        /// 
        /// backgroundWorker进度更新调用函数,用来显示倒计数值
        /// 
        /// 
        /// 
        private void backgroundWorkerCounter_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //本方法在GUI线程,更新文本显示的计数值
            textBoxCounter.Text = e.ProgressPercentage.ToString();
        }
        /// 
        /// backgroundWorker完成后的扫尾工作
        /// 
        /// 
        /// 
        private void backgroundWorkerCounter_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Cancelled==true)
            {
                //如果因为取消而完成,显示相应信息
                labelMessage.Text = "counter cancelled by user";
            }
            else
            {
                //否则,即为正常完成倒计数
                labelMessage.Text = "count down completed";
            }
        }
        /// 
        /// Form中点击Start按钮触发此方法,启动backgroundWorker
        /// 
        /// 
        /// 
        private void buttonStart_Click(object sender, EventArgs e)
        {
            backgroundWorkerCounter.RunWorkerAsync((int) numericUpDownCounterStart.Value);
        }
        /// 
        /// For中Stop按钮触发此方法,向backgroundWorker发出取消执行事件
        /// 
        /// 
        /// 
        private void buttonStop_Click(object sender, EventArgs e)
        {
            backgroundWorkerCounter.CancelAsync();
        }
    }
}

你可能感兴趣的:(编程,技术,c#)