使用BackgroundWorker组件进行异步操作编程
本文介绍了BackgroundWorker组件的功能及在基于事件的异步操作编程中的应用,并对组件的实现原理进行简述。在应用程序中,可能会遇到一些执行耗时的功能操作,比如数据下载、复杂计算及数据库事务等,一般这样的功能会在单独的线程上实现,执行结束后结果显示到用户界面上,这样可避免造成用户界面长时间无响应情况。在.NET 2.0及以后的版本中,FCL提供了BackgroundWorker组件来方便的实现这些功能要求。
|
publicvoidRunWorkerAsync();
publicvoidRunWorkerAsync(Object argument);
|
|
publicvoid CancelAsync();
|
|
publicvoidReportProgress(int percentProgress);
publicvoidReportProgress(int percentProgress,Object userState);
|
|
publicboolCancellationPending { get; }
publicboolWorkerReportsProgress { get; set; }
publicboolWorkerSupportsCancellation { get; set; }
|
|
publicbool IsBusy { get; }
|
|
publiceventDoWorkEventHandler DoWork;
publiceventProgressChangedEventHandler ProgressChanged;
publiceventRunWorkerCompletedEventHandler RunWorkerCompleted;
|

|
private System.ComponentModel.BackgroundWorker backgroundWorker1;
private void InitializeBackgoundWorker()
{
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
this.backgroundWorker1.WorkerReportsProgress = true;
this.backgroundWorker1.WorkerSupportsCancellation = true;
this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
}
|
|
private void startAsyncButton_Click(object sender, EventArgs e)
{
resultLabel.Text = String.Empty;
this.numericUpDown1.Enabled = false;
this.startAsyncButton.Enabled = false;
this.cancelAsyncButton.Enabled = true;
//获取计算数值.
int numberToCompute = (int)numericUpDown1.Value;
//启动异步操作.
backgroundWorker1.RunWorkerAsync(numberToCompute);
}
|
|
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
e.Result = ComputeAdd((int)e.Argument, worker, e);
}
|
|
private long ComputeAdd(int n, BackgroundWorker worker, DoWorkEventArgs e)
{
long result = 0;
for (int i = 1; i <= n; i++)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
result += i;
Thread.Sleep(500);
int percentComplete = (int)((float)i / (float)n * 100);
worker.ReportProgress(percentComplete);
}
}
return result;
}
|
|
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
|
|
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
resultLabel.Text = "Canceled";
}
else
{
resultLabel.Text = e.Result.ToString();
}
this.numericUpDown1.Enabled = true;
startAsyncButton.Enabled = true;
cancelAsyncButton.Enabled = false;
}
|

|
public ProcessForm(BackgroundWorker backgroundWorker1)
{
InitializeComponent();
this.backgroundWorker1 = backgroundWorker1;
this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
}
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Close();
}
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
private void cancelButton1_Click(object sender, EventArgs e)
{
this.backgroundWorker1.CancelAsync();
this.cancelButton1.Enabled = false;
this.Close();
}
|
|
private void startAsyncButton_Click(object sender, EventArgs e)
{
// ...
backgroundWorker1.RunWorkerAsync(numberToCompute);
ProcessForm form = new ProcessForm(this.backgroundWorker1);
form.ShowDialog(this);//模式
//form.Show(this);//非模式
}
|
|
publicvoidPost(SendOrPostCallback d,Object arg);
publicvoidPostOperationCompleted(SendOrPostCallback d,Object arg);
|
|
publicdelegatevoidSendOrPostCallback(Object state);
|
|
private delegate void WorkerThreadStartDelegate(object argument);
private readonly WorkerThreadStartDelegate threadStart;
public BackgroundWorker()
{
this.threadStart = new WorkerThreadStartDelegate(this.WorkerThreadStart);
//…
}
|
|
public void RunWorkerAsync(object argument)
{
if (this.isRunning)
{
throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerAlreadyRunning"));
}
this.isRunning = true;
this.cancellationPending = false;
this.asyncOperation = AsyncOperationManager.CreateOperation(null);
this.threadStart.BeginInvoke(argument, null, null);
}
|
|
private void WorkerThreadStart(object argument)
{
object result = null;
Exception error = null;
bool cancelled = false;
try
{
DoWorkEventArgs e = new DoWorkEventArgs(argument);
this.OnDoWork(e);
if (e.Cancel)
{
cancelled = true;
}
else
{
result = e.Result;
}
}
catch (Exception exception2)
{
error = exception2;
}
RunWorkerCompletedEventArgs arg = new RunWorkerCompletedEventArgs(result, error, cancelled);
this.asyncOperation.PostOperationCompleted(this.operationCompleted, arg);
}
|
|
public void ReportProgress(int percentProgress, object userState)
{
if (!this.WorkerReportsProgress)
{
throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerDoesntReportProgress"));
}
ProgressChangedEventArgs arg = new ProgressChangedEventArgs(percentProgress, userState);
if (this.asyncOperation != null)
{
this.asyncOperation.Post(this.progressReporter, arg);
}
else
{
this.progressReporter(arg);
}
}
|
|
public BackgroundWorker()
{
this.threadStart = new WorkerThreadStartDelegate(this.WorkerThreadStart);
this.operationCompleted = new SendOrPostCallback(this.AsyncOperationCompleted);
this.progressReporter = new SendOrPostCallback(this.ProgressReporter);
}
private void ProgressReporter(object arg)
{
this.OnProgressChanged((ProgressChangedEventArgs)arg);
}
private void AsyncOperationCompleted(object arg)
{
this.isRunning = false;
this.cancellationPending = false;
this.OnRunWorkerCompleted((RunWorkerCompletedEventArgs)arg);
}
|
|
public void RunWorkerAsync(object argument)
{
if (this.isRunning)
{
throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerAlreadyRunning"));
}
this.isRunning = true;
this.cancellationPending = false;
this.asyncOperation = AsyncOperationManager.CreateOperation(null);
this.threadStart.BeginInvoke(argument, null, null);
}
public void CancelAsync()
{
if (!this.WorkerSupportsCancellation)
{
throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerDoesntSupportCancellation"));
}
this.cancellationPending = true;
}
|
本文应用地址:http://blog.csdn.net/zhzuo/archive/2008/07/23/2699305.aspx
使用BackgroundWorker组件进行异步操作编程的更多相关文章
- C# BackgroundWorker组件学习入门介绍
C# BackgroundWorker组件学习入门介绍 一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能 ...
- C# BackgroundWorker组件学习
C# BackgroundWorker组件学习 C# BackgroundWorker组件学习 一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用Ba ...
- BackgroundWorker组件
BackgroundWorker组件封装了后台线程的操作,并且直接利用线程池,无需自己管理线程池等复杂问题. 它主要适用于 比如界面后台加载数据,进度显示,上传下载文件,日月结等 这些都是繁重的劳动, ...
- backgroundworker组件的使用
本文转载:http://www.cnblogs.com/inforasc/archive/2009/10/12/1582110.html BackgroundWorker 组件用来执行诸如数据库事务. ...
- C# Winform backgroundWorker组件使用
BackgroundWorker 组件用来执行诸如数据库事务.文件下载等耗时的异步操作. 开始 在应用程序中添加一个BackgroundWorker实例,如果用的是VS,可以从工具上直接拖到应用程序: ...
- 使用BackgroundWorker组件
BackgroundWorker 组件用来执行诸如数据库事务.文件下载等耗时的异步操作. 开始 在应用程序中添加一个BackgroundWorker实例,如果用的是VS,可以从工具上直接拖到应用程序: ...
- BackgroundWorker组件学习
今天看到别人的博客中提到了BackgroundWorker组件.在现在的系统中有见到过这个组件,由于实际应用的系统中逻辑比较复杂所以也没深入去看.今天凑巧看到了一个关于BackgroundWorker ...
- BackgroundWorker组件使用总结
首先在窗体拖入一个BackgroundWorker组件,根据功能需要设置BackgroundWorker的属性 WorkerSupportsCancellation = true; 允许取消后台正在执 ...
- 实验五 CC2530平台上ADC组件的TinyOS编程
实验五 CC2530平台上ADC组件的TinyOS编程 实验目的: 加深和巩固学生对于TinyOS编程方法的理解和掌握 让学生初步掌握传感器的ADC组件应用方法 学生通过本实验能够初步的了解和掌握CC ...
随机推荐
- C++教材
C++语言: 1.<Essential C++>:Stanley B.Lipman著. 旁枝暂略,主攻核心,轻薄短小.附习题与解答,适合刚開始学习的人. 2.<The C++ Pro ...
- 基于AdaBoost的人脸检测
原地址:http://blog.csdn.net/celerychen2009/article/details/8839097 人脸检测和人脸识别都是属于典型的机器学习的方法,但是他们使用的方法却相差 ...
- 关于java堆内存溢出的几种情况(转)
[情况一]: java.lang.OutOfMemoryError: Java heap space:这种是java堆内存不够,一个原因是真不够,另一个原因是程序中有死循环: 如果是java堆内存不够 ...
- 通过YAJL生成json语句
这里主要介绍的是怎样通过yajl生成一个json语句.方法通过代码就能够非常清楚的看到了,只是这里仅仅加入了字符串. 假设须要加入其它类型的,能够查考yajl的手冊,调用其它函数进行加入. /* * ...
- [Linux]Centos git报错fatal: HTTP request failed
在使用git pull.git push.git clone会报类似例如以下的错误: error: The requested URL returned error: 401 Unauthorized ...
- 约瑟夫问题--list模拟循环链表
约瑟夫问题 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描写叙述 n个人想玩残酷的死亡游戏,游戏规则例如以下: n个人进行编号,分别 ...
- 【十一年】注入框架RoboGuice采用:(Your First Injection into a Custom View class)
上一篇我们简单的介绍了一下RoboGuice的使用([十]注入框架RoboGuice使用:(Your First Testcase)),今天我们来看下自己定义View的注入(Custom View). ...
- OSPF拓扑排错报告
OSPF排错报告 故障点一:PPP链路故障 故障现象: R2和R4之间的PPP链路一会down一会UP 故障分析: 1) ppp 认证类型是否一致 2) ppp chap认证用 ...
- SE 2014年4月17日
描述BGP路由属性 MED.首选值 的特点 MED相当于IGP协议中的度量值,在其他条件相同时,当本自治系统有多条到达外部自治系统的链路时,MED值小的路由优选.MED属性只能在两个自治系统间传递. ...
- apache cxf之 一个简单的JAX-WS服务程序
推荐一本apache cxf的书籍: apache cxf的配置,这边就不做介绍了.请参照我关于它配置的博文. 开发步骤: 1.新建Java project,build path引入cxf runti ...