BackgroundWorker 使用范例

在 WinForm 的开发过程中, 难免会有大量的操作耗时比较严重, 这时界面会卡死, 无法拖动, 用户体验不佳。这种情况下, BackgroundWorker 是最佳选择, 它提供了异步操作, 而且可以提供进度报告, 还可以取消操作。

不说废话了, 步入正轨。咱们做一个累加的程序:

1. 创建一个 Windows 应用程序;

2. 如下图, 创建好窗体上的相关控件, 并拖入 backgroundworker 控件;


3. 在 backgroundworker1 上右键, 看其属性中的 3 个事件, 分别双击:


4. 下面就直接贴代码了, 注释非常清晰, 相信你能看懂。

先是窗体的 Form1.cs 代码:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApp3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //允许 backgroundWorker 报告进度
            this.backgroundWorker1.WorkerReportsProgress = true;
            //backgroundWorker 支持取消异步操作
            this.backgroundWorker1.WorkerSupportsCancellation = true;
            //是否捕获对错误线程的调用。在 DoWork 中出现对控件的使用时必须配合这一句。
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        //在另一个线程上运行的事件处理程序
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            //下面的语句(在注释 CheckForIllegalCrossThreadCalls = false 之后)会提示有异常:
            //System.InvalidOperationException:“线程间操作无效: 从不是创建控件“txtResult”的线程访问它。”
            this.txtResult.Width = 101;

            int i = 1;
            int total = 0;
            for (; i <= this.nudLastNum.Value; i++)
            {
                //如果应用程序已请求取消后台操作
                if (worker.CancellationPending == true)
                {
                    //取消事件
                    e.Cancel = true;
                    break;
                }
                total += i;
                Thread.Sleep(40);
                worker.ReportProgress( Convert.ToInt32( (i*100)/this.nudLastNum.Value ) );
            }

            e.Result = total;
        }
        //进度发生变化时事件
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //修改进度条的值为 backgroundWorker1 的异步任务进度百分比
            this.progressBar1.Value = e.ProgressPercentage;
        }
        //当辅助线程完成时发生(无论取消、异常、完成)
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            string baseInfo = string.Empty;
            if (e.Cancelled == true)
            {
                baseInfo = "用户已取消!";
            }
            else if (e.Error != null)
            {
                baseInfo = "Error: " + e.Error.Message;
            }
            else
            {
                baseInfo = "顺利完成!";
                //只有顺利完成,才能用 e.Result 的结果。否则只能想其它办法
                this.txtResult.Text = e.Result.ToString();
            }
            this.lblExecInfo.Text = baseInfo;
            SetBtnEnabled(false);
        }
        //开始按钮
        private void btnStart_Click(object sender, EventArgs e)
        {
            //如果 backgroundWorker1 没有运行异步操作
            if (backgroundWorker1.IsBusy != true)
            {
                SetBtnEnabled(true);
                this.txtResult.Text = "";
                //开始执行后台操作
                backgroundWorker1.RunWorkerAsync();
            }
        }
        //取消按钮
        private void btnCancel_Click(object sender, EventArgs e)
        {
            //如果支持异步取消操作
            if (backgroundWorker1.WorkerSupportsCancellation == true)
            {
                backgroundWorker1.CancelAsync();
                SetBtnEnabled(false);
            }
        }
        //设置按钮的启用禁用状态
        private void SetBtnEnabled(bool start)
        {
            this.btnCancel.Enabled = start;
            this.btnStart.Enabled = !start;
        }
    }
}


设计器 Form1.Designer.cs 代码如下:

namespace WindowsFormsApp3
{
    partial class Form1
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.nudLastNum = new System.Windows.Forms.NumericUpDown();
            this.label2 = new System.Windows.Forms.Label();
            this.txtResult = new System.Windows.Forms.TextBox();
            this.btnStart = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
            this.lblExecInfo = new System.Windows.Forms.Label();
            ((System.ComponentModel.ISupportInitialize)(this.nudLastNum)).BeginInit();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(13, 13);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(47, 12);
            this.label1.TabIndex = 0;
            this.label1.Text = "从1加到";
            // 
            // nudLastNum
            // 
            this.nudLastNum.Location = new System.Drawing.Point(66, 9);
            this.nudLastNum.Name = "nudLastNum";
            this.nudLastNum.Size = new System.Drawing.Size(120, 21);
            this.nudLastNum.TabIndex = 1;
            this.nudLastNum.Value = new decimal(new int[] {
            100,
            0,
            0,
            0});
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(193, 13);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(53, 12);
            this.label2.TabIndex = 2;
            this.label2.Text = "结果为:";
            // 
            // txtResult
            // 
            this.txtResult.Location = new System.Drawing.Point(253, 9);
            this.txtResult.Name = "txtResult";
            this.txtResult.Size = new System.Drawing.Size(100, 21);
            this.txtResult.TabIndex = 3;
            // 
            // btnStart
            // 
            this.btnStart.Location = new System.Drawing.Point(15, 86);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(165, 23);
            this.btnStart.TabIndex = 4;
            this.btnStart.Text = "开    始";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            // 
            // btnCancel
            // 
            this.btnCancel.Location = new System.Drawing.Point(188, 86);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new System.Drawing.Size(165, 23);
            this.btnCancel.TabIndex = 5;
            this.btnCancel.Text = "取  消";
            this.btnCancel.UseVisualStyleBackColor = true;
            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
            // 
            // progressBar1
            // 
            this.progressBar1.Location = new System.Drawing.Point(15, 116);
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.Size = new System.Drawing.Size(338, 23);
            this.progressBar1.TabIndex = 6;
            // 
            // backgroundWorker1
            // 
            this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
            this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
            this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
            // 
            // lblExecInfo
            // 
            this.lblExecInfo.AutoSize = true;
            this.lblExecInfo.Location = new System.Drawing.Point(15, 39);
            this.lblExecInfo.Name = "lblExecInfo";
            this.lblExecInfo.Size = new System.Drawing.Size(53, 12);
            this.lblExecInfo.TabIndex = 7;
            this.lblExecInfo.Text = "执行信息";
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(369, 147);
            this.Controls.Add(this.lblExecInfo);
            this.Controls.Add(this.progressBar1);
            this.Controls.Add(this.btnCancel);
            this.Controls.Add(this.btnStart);
            this.Controls.Add(this.txtResult);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.nudLastNum);
            this.Controls.Add(this.label1);
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "累加";
            ((System.ComponentModel.ISupportInitialize)(this.nudLastNum)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.NumericUpDown nudLastNum;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox txtResult;
        private System.Windows.Forms.Button btnStart;
        private System.Windows.Forms.Button btnCancel;
        private System.Windows.Forms.ProgressBar progressBar1;
        private System.ComponentModel.BackgroundWorker backgroundWorker1;
        private System.Windows.Forms.Label lblExecInfo;
    }
}


百余行的代码, 就可以完成这么优秀的功能, 是不是很神奇?

猜你喜欢

转载自blog.csdn.net/yenange/article/details/80795281