以下内容仅作为学习提高记录,有错误恳请批评。
引用:1.C#高级编程第七版。
2.http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker(v=vs.110).aspx
1.前言
在windows窗体和WPF等控件绑定到一个线程上,这时,对于每个控件,只能从创建控件的主线程中调用方法,而对于一个后台线程,就无法从主线程中访问UI控件。
对于这种可以通过异步模式实现。即创建他的线程之外的线程调用Invoke(),BeginInvoke(),EndInvoke()方法和InvokeRequried属性等异步版本。
同时可以解决界面假死现象。
2.BackgroundWorker类
BackgroundWorker类是异步事件模式的一种实现方案。
属性(摘录部分):
CancellationPending 获取一个值,指示应用程序是否已请求取消后台操作。
WorkerReportsProgress 获取或设置一个值,该值指示 BackgroundWorker 能否报告进度更新。
WorkerSupportsCancellation 获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消。
方法(摘录部分):
CancelAsync 请求取消挂起的后台操作
OnDoWork 引发DoWork事件
OnProgressChanged 引发 ProgressChanged 事件。
OnRunWorkerCompleted 引发 RunWorkerCompleted 事件。
ReportProgress 引发 ProgressChanged 事件。
RunWorkerAsync() 开始执行后台操作。
事件(摘录部分):
DoWork 调用 RunWorkerAsync 时发生。
ProgressChanged 调用 ReportProgress 时发生。
RunWorkerCompleted 当后台操作已完成、被取消或引发异常时发生
3.DEMO
若要为后台操作做好准备,请添加 DoWork 事件的事件处理程序。 在此事件处理程序中调用耗时的操作。 若要开始此操作,请调用 RunWorkerAsync。 若要收到进度更新的通知,请处理 ProgressChanged 事件。 若要在操作完成时收到通知,请处理 RunWorkerCompleted 事件。
namespace _11._1_BackgroundWorker { /// <summary> /// 基于事件的异步模式 /// 开始事件:DoWork+= /// 完成时间事件:RunWorkerCompleted+= /// 取消功能:把WorkerSupportCancellation属性设置为true就支持取消功能。也可以通过CancelAsync()方法来取消。 /// 验证是否取消工作:CancellationPending属性 /// 进度信息:WorkerReportProgess属性指定正在进行的任务是否返回进度信息。如果返回,可指定ProgessChanged事件来接受进度信息。完成调用ReportProgess() /// 好处:可以切换到主调线程上,参数在线程之间相互调用。同时解决窗体假死现象 /// </summary> public partial class Form1 :Form { private BackgroundWorker backgroundWorker;// public Form1() { InitializeComponent(); backgroundWorker = new BackgroundWorker(); backgroundWorker.WorkerSupportsCancellation = true;//取消功能:必须把设置为True; backgroundWorker.WorkerReportsProgress = true;// backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);//开始异步操作结果 backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);//进度信息 backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);//完成异步操作结果 } void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; } void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) this.txtResult.Text = "Cancelled"; else this.txtResult.Text = e.Result.ToString(); } void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { var t = e.Argument as Tuple<int, int>; for (int i = 0; i <= 10; i++) { System.Threading.Thread.Sleep(500); backgroundWorker.ReportProgress(i * 10); if (backgroundWorker.CancellationPending) { e.Cancel = true; return; } } e.Result = t.Item1 + t.Item2;//设置异步操作的结果。 } private void button1_Click(object sender, EventArgs e) { if(!string.IsNullOrEmpty(txtX.Text)) backgroundWorker.RunWorkerAsync(Tuple.Create<int,int>(int.Parse(txtX.Text), int.Parse(txtY.Text)));//启动BackgroundWorker控件,并传递参数(x,y) } private void Form1_MouseMove(object sender, MouseEventArgs e) { this.txtX.Text = e.X.ToString(); this.txtY.Text = e.Y.ToString(); } private void button2_Click(object sender, EventArgs e) { backgroundWorker.CancelAsync(); } } }