使用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 ...
随机推荐
- sql,nosql
1. 关系型数据库 关系型数据库,是指采用了关系模型来组织数据的数据库. 关系模型是在1970年由IBM的研究员E.F.Codd博士首先提出的,在之后的几十年中,关系模型的概念得到了充分的发展并逐渐成 ...
- webapi Task
webapi+Task并行请求不同接口实例 标题的名称定义不知道是否准确,不过我想表达的意思就是使用Task特性来同时请求多个不同的接口,然后合并数据:我想这种场景的开发对于对接过其他公司接口的人不会 ...
- BaiduMap_SDK_DEMO_3.0.0_for_Xamarin.Android_by_imknown
2.4.2 已稳定, 同一时候已经放置到分支/Release 2.4.2了. 3.0.0 已开发完毕, 可是不推荐大家用于项目中, 请观望或者自己进一步调试. 个人感觉尽管3.0.0简化了开发, 可是 ...
- AOP 之 6.1 AOP基础 ——跟我学spring3(转)
http://jinnianshilongnian.iteye.com/blog/1418596
- vmware: The file system upon which * resides is critically low on free space.
The file system upon which ******.localized/Windows XP Professional.vmwarevm' resides is critically ...
- jstl的小问题
jstl试了半天,终于知道错在哪里了! 这是jsp中的代码 从select中取得user_id:看清楚了 是user_id:小写第一位; <table width="50%" ...
- Memcached在.net中的应用
一.MemCached下载 服务端下载:http://memcachedproviders.codeplex.com/ client下载:path=/trunk">http://sou ...
- hdu 3790 (最短路径问题dijkstra)
主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起 ...
- 2012天津E题
给我们n个坐标点和一个距离d,表示车开m米就没油了. 然后要选几个点建立油站,使得能够从1出发遍历所有的点,然后回到1. 并且规定1这个点必须有油站,在第i个点建立油站的费用是 2^(i-1) 因为 ...
- 宏碁宣布Liquid Jade智能机和Leap袖口
据科技网站Android Community 4月29日覆盖,宏碁29公布的新智能机Liquid Jade而随着智能手镯部署Liquid Leap.尽管宏碁已经宣布了一项新的外部基本信息.但价格格和商 ...