Winfom 使用 BackgroundWorker 实现进度条

BackgroundWorker 简介(来自百度)

  BackgroundWorker是·net里用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 始终处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题。

  场景:界面加载数据量略大或者执行一个比较耗时的操作,如果在该操作未完成之前操作界面,会出现停止响应的情况,这个时候界面就会出现假死状态,当我们用到 BackgroundWorker 时可以良好的提示用户加载进度。

属性

  1.WorkerReportsProgress:辅助线程是否报告进度。

  2.WorkerSupportsCancellation:辅助线程是否支持取消。

  3.CancellationPending:获取一个值,指示应用程序是否已请求取消后台操作。

  4.IsBusy:获取一个值,指示 BackgroundWorker 是否正在运行一步操作。

  5.WorkerReportsProgress:获取或设置一个值,该值指示 BackgroundWorker 能否报告进度更新。 

方法

  1.RunWorkerAsync()开始执行后台操作。(调用该方法后,将触发 BackgroundWorker.DoWork 事件,并以异步的方式执行 DoWork 事件中的代码)

  2.ReportProgress(): 引发 BackgroundWorker.ProgressChanged 事件。(调用该方法后,将触发BackgroundWorker. ProgressChanged事件。另外,该方法包含了一个int类型的参数percentProgress,用来表示当前异步操作所执行的进度百分比)

  3.CancelAsync():请求取消挂起的后台操作。(调用该方法将使 BackgroundWorker.CancellationPending 属性设置为True)

事件

  1.DoWork:操作开始时在另一个线程上运行的事件处理程序。(用于承载异步操作,当调用 BackgroundWorker.RunWorkerAsync() 时触发)

  2.ProgressChanged:当辅助线程指示某些操作已经进行时引发。(当调用 BackgroundWorker.ReportProgress(int percentProgress) 方式时触发该事件)

  3.RunWorkerCompleted:当辅助线程完成(无论成功、失败还是取消)时引发。

代码案例

Form1窗体设计:

 

Form1代码:

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

namespace BackgroundWorkerDemo
{
    public partial class Form1 : Form
    {
        ProgressForm form;

        int maxValue = 0;

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

        private void InitializeBackgroundWorker()
        {
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            maxValue = Convert.ToInt32(textBox1.Text);
            form = new ProgressForm();  //显示进度条窗体
            form.MaxProcessBarValue = maxValue;

            this.backgroundWorker1.RunWorkerAsync();  //运行backgroundWorker组件

            form.ShowDialog(this);
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for(int i=0;i< maxValue;i++)
            {
                if(form.IsCancle)
                {
                    backgroundWorker1.CancelAsync();
                }
                
                if(backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                else
                {
                    form.ChangeProcessValue(i);
                    Thread.Sleep(100);
                }
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.ToString());
                return;
            }
            if (!e.Cancelled)
                MessageBox.Show("处理完毕!");
            else
                MessageBox.Show("处理终止!");
       form.Close(); } } }

 

ProgressForm窗体设计:

 

ProgressForm代码:

using System;
using System.Windows.Forms;

namespace BackgroundWorkerDemo
{
    public partial class ProgressForm : Form
    {
        /// <summary>
        /// 进度条的最大值
        /// </summary>
        public int MaxProcessBarValue { get; set; }

        public bool IsCancle { get; set; } = false;
        public ProgressForm()
        {
            InitializeComponent();

            this.Load += Form2_Load;
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            this.progressBar1.Maximum = this.MaxProcessBarValue;
            this.progressBar1.Minimum = 0;
        }

        //取消
        private void btnCancel_Click(object sender, EventArgs e)
        {
            try
            {
                this.btnCancel.Enabled = false;
                IsCancle = true;
                this.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString(), ex);
            }
        }
        internal void ChangeProcessValue(int v)
        {
            try
            {
                this.Invoke(new Action(() =>
                {
                    this.progressBar1.Value = v + 1;  //获取异步任务的进度百分比
                    label1.Text = $"完成比:{ v + 1} / {this.MaxProcessBarValue}  {Math.Round((v+1)*1.0/this.MaxProcessBarValue * 100,2)}%";
                }));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString(), ex);
            }
        }
    }
}

 

结果:

源码:

  链接: https://pan.baidu.com/s/1Ba5iWWFRKV6wjcHl39qpIQ

  提取码: sj7e

posted @ 2020-01-16 14:11  没事儿写个bug  阅读(659)  评论(0编辑  收藏  举报