C# 后台线程编程 - BackgroundWorker

C# 后台线程编程 - BackgroundWorker

用途

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

技术解释

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

  2. 在其属性设置支持WorkerReportProgress和WorkerSupportsCancellation
    在这里插入图片描述

  3. 在backgroundWorker属性》事件》Asynchronous》下面3个事件的空白处双击,创建空白的事件响应方法。
    在这里插入图片描述

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

范例代码

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;
/// <summary>
/// 显示一个计数的范例,演示Background Worker的编程
/// </summary>
namespace bgwCounter
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// 自动生成的Form实例化
        /// </summary>
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// BackgroundWorker主要工作在此,方法框架是VS自动生成的
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        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);
            }
        }
        /// <summary>
        /// backgroundWorker进度更新调用函数,用来显示倒计数值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorkerCounter_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //本方法在GUI线程,更新文本显示的计数值
            textBoxCounter.Text = e.ProgressPercentage.ToString();
        }
        /// <summary>
        /// backgroundWorker完成后的扫尾工作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorkerCounter_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Cancelled==true)
            {
                //如果因为取消而完成,显示相应信息
                labelMessage.Text = "counter cancelled by user";
            }
            else
            {
                //否则,即为正常完成倒计数
                labelMessage.Text = "count down completed";
            }
        }
        /// <summary>
        /// Form中点击Start按钮触发此方法,启动backgroundWorker
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonStart_Click(object sender, EventArgs e)
        {
            backgroundWorkerCounter.RunWorkerAsync((int) numericUpDownCounterStart.Value);
        }
        /// <summary>
        /// For中Stop按钮触发此方法,向backgroundWorker发出取消执行事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonStop_Click(object sender, EventArgs e)
        {
            backgroundWorkerCounter.CancelAsync();
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值