C# 提供了BackgroundWorker功能非常强大,可以将某项工作放到后台运行,可以让后台报告进度,可以取消后台工作......
BackgroundWorker的上述功能是通过
1. 三个主要事件
DoWork--后台事件。定义完成需要做的后台工作
ProgressChanged--进度报告事件。定义有进度报告产生时进行要做的工作
RunWorkerCompleted--后台完成事件。定义后台工作完成后要做的工作
2 2+x个属性:
WorkerReportsProgress -- 是否允许报告进度
WorkerSupportsCancellation -- 是否允许取消
有些属性是在运行时设置的,不在可视化区,如
backgroundWorker1.CancellationPending --执行CancelAsync()会设置
DoWorkEventArgs.Cancel --设置此属性,通知RunWorkerCompleted已被取消
3.三个方法
backgroundWorker1.RunWorkerAsync(); //开始异步工作
backgroundWorker1.CancelAsync(); //取消异步工作
//需要注意的是,执行了CancelAsync()后,只是设置了一个CancellationPending标志,后台工作并没有真正挺下来,需要明确的代码退出后台工作
backgroundWorker1.ReportProgress(int progress, object userstate); //报告进度
4. 可视化开发。VS开发环境中,工具箱提供了可视化的控件。
简单使用步骤如下
1)往FORM中拖拽一个BackgroundWorker控件
2)设置两个属性:
WorkerReportsProgress -- 是否允许报告进度
WorkerSupportsCancellation -- 是否允许取消
3)写三个事件的代码
DoWork、ProgressChanged、RunWorkerCompleted
4)报告进度
某些耗时较长的工作,我们希望在工作中途报告进度,可在DoWork事件中,加入
backgroundWorker1.ReportProgress(int progress, object userstate)代码报告进度,userState可用于返回其他数据
5)终止后台工作
(1)执行CancelAsync(),此代码设置CancellationPending标志
(2)后台工作中用代码检测CancellationPending标志,检测到CancellationPending后
处理善后工作
可选:设置DoWorkEventArgs 参数的Cancel属性为true(e.Cancel=True)
终止后台工作(return)
(3)可选:终止后处理
RunWorkerCompleted事件中检测RunWorkerCompletedEventArgs 参数,是否为终止
RunWorkerCompletedEventArgs.Cancel=true(第二部的设置值)
终止后处理代码
5. 多说无益,上酸菜
1)FORM设置
2)上代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; namespace VisibleBackgroundWorker { public partial class Form1 : Form { int total = 100; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } /// <summary> /// 后台作业代码 /// </summary> /// <param name="sender"></param> /// <param name="e">e.Cancel用于返回终止标志,e.Result用于返回数据,e.Argument为传入的参数</param> private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { List<string> itemList = new List<string>(); for (int i = 0; i < total; i++) { if (backgroundWorker1.CancellationPending) { //如果执行了CancelAsync() e.Cancel = true; //设置后台作业取消标志 return; } string item = "item " + i.ToString(); backgroundWorker1.ReportProgress(i,item); itemList.Add(item); System.Threading.Thread.Sleep(500); } e.Result = itemList;//返回结果 } /// <summary> /// 进度报告事件,可用于显示进度、中间结果等 /// </summary> /// <param name="sender"></param> /// <param name="e">e.ProgressPercentage为进度,e.UserState可定义的回传数据</param> private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { int p = e.ProgressPercentage; string item = e.UserState as string; label1.Text = "Progress:" + p.ToString(); listBox1.Items.Add(item); } /// <summary> /// 后台作业完成事件 /// </summary> /// <param name="sender"></param> /// <param name="e">e.Cancel为是否被终止的标志</param> private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if(e.Cancelled) {//中途终止 label1.Text = "Cancel!"; } else {//正常结束 label1.Text = "Complete!"; } listBox2.Items.AddRange((e.Result as List<string>).ToArray()); } private void button1_Click(object sender, EventArgs e) { //终止后台作业标志(设置CancellationPending标志) backgroundWorker1.CancelAsync(); } private void btnGo_Click(object sender, EventArgs e) {//开始后台作业 int arg = 1;//传到后台作业的参数 backgroundWorker1.RunWorkerAsync(arg); } } }