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