`
devgis
  • 浏览: 134241 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

C#BackgroundWorker类详细说明

 
阅读更多

BackgroundWorker类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题。

若要在后台执行耗时的操作,请创建一个BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。

若要设置后台操作,请为DoWork事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用RunWorkerAsync。若要收到进度更新通知,请对ProgressChanged事件进行处理。若要在操作完成时收到通知,请对RunWorkerCompleted事件进行处理。

您必须非常小心,确保在DoWork事件处理程序中不操作任何用户界面对象。而应该通过ProgressChangedRunWorkerCompleted事件与用户界面进行通信。

BackgroundWorker事件不跨AppDomain边界进行封送处理。请不要使用BackgroundWorker组件在多个AppDomain中执行多线程操作。

如果后台操作需要参数,请在调用RunWorkerAsync时给出参数。在DoWork事件处理程序内部,可以从DoWorkEventArgs.Argument属性中提取该参数。

有关BackgroundWorker的更多信息,请参见如何:在后台运行操作

摘自:http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker%28VS.80%29.aspx


.net 2.0 BackgroundWorker类详细用法

1. 从工具栏拖一个BackgroundWorker控件,设置其属性WorkerReportsProgress为true

2. 要让worker开始工作,执行如下代码:
mBackgroundWorker.RunWorkerAsync(arg);
这里有重写,如果不需要传递参数直接mBackgroundWorker.RunWorkerAsync();

3. 编辑DoWork事件代码:
e.Argument为mBackgroundWorker.RunWorkerAsync(arg);对应的参数
之所以使用进度条,肯定是有循环的,在循环中报告进度:
worker.ReportProgress(i * 100 / totalNum, obj );
其中第一个参数是当前进度的百分之多少,obj为你要传递的UserState,如果没有可以不要

4. 编辑ProgressChanged事件代码:
e.ProgressPercentage为进度的百分数,e.UserState为刚才传递过来的object
在这个事件中可以调用ui的进度条和其他控件:
mToolStripProgressBar.Value = e.ProgressPercentage;

5. 编辑RunWorkerCompleted事件代码:
工作完成了告诉ui


示例代码:一个简单的刷网页流量的小工具

usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Net;
usingSystem.Threading;

namespaceshua
{
publicpartialclassForm1:Form
{
publicForm1()
{
InitializeComponent();
}

privatevoidbutton1_Click(objectsender,EventArgse)
{
backgroundWorker1.RunWorkerAsync(textBox1.Text);
}

privatevoidbackgroundWorker1_DoWork(objectsender,DoWorkEventArgse)
{
BackgroundWorkerworker=(BackgroundWorker)sender;
stringurl=e.Argument.ToString();
intnum=int.Parse(textBox2.Text);
for(inti=0;i<num;i++)
{
if(!worker.CancellationPending)
{
WebRequestrequest=WebRequest.Create(url);
WebResponseresponse=request.GetResponse();
response.Close();

Thread.Sleep(100);
worker.ReportProgress(i*100/num,i);
}
}
}

privatevoidbackgroundWorker1_ProgressChanged(objectsender,ProgressChangedEventArgse)
{
progressBar1.Value=e.ProgressPercentage;
label3.Text=e.UserState.ToString();
}

privatevoidbackgroundWorker1_RunWorkerCompleted(objectsender,RunWorkerCompletedEventArgse)
{
MessageBox.Show("ok");
}
}
}

摘自:http://blog.csdn.net/lanwilliam/archive/2008/06/06/2516809.aspx


当要加载大量数据的时候,往往程序界面会卡一会,这时候使用BackgroundWorker来进行后台的操作加载数据就不会使界面卡了,而且还可以调用一个“正在加载”的窗体来更好的来进行交互。不能在DoWork里面调用就是!结束窗体的写在RunWorkerCompleted里面。

参考资料:
1.VS2005中BackgroundWorker组件的使用经验
2.C# BackgroundWorker实现WinForm异步操作的例子
3.在UI上使用BackgroundWorker


C# BackgroundWorker 使用方法

http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker(VS.80).aspx

BackgroundWorker类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题。

若要在后台执行耗时的操作,请创建一个BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。

若要设置后台操作,请为DoWork事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用RunWorkerAsync。若要收到进度更新通知,请对ProgressChanged事件进行处理。若要在操作完成时收到通知,请对RunWorkerCompleted事件进行处理。

下面代码演示如何用BackgroundWorker计算斐波那契数列并表示当前进度

/////////////////////////////Form1.cs///////////////////////////////

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
public partial class Form1 : Form
{
private int numberToCompute = 0;
private int highestPercentageReached = 0;
public Form1()
{
InitializeComponent();
InitializeBackgoundWorker();
}
// Set up the BackgroundWorker object by
// attaching event handlers.
private void InitializeBackgoundWorker()
{
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}
private void startAsyncButton_Click(System.Object sender, System.EventArgs e)
{
// Reset the text in the result label.
resultLabel.Text = String.Empty;

// Disable the UpDown control until
// the asynchronous operation is done.
this.numericUpDown1.Enabled = false;

// Disable the Start button until
// the asynchronous operation is done.
this.startAsyncButton.Enabled = false;

// Enable the Cancel button while
// the asynchronous operation runs.
this.cancelAsyncButton.Enabled = true;

// Get the value from the UpDown control.
numberToCompute = (int)numericUpDown1.Value;

// Reset the variable for percentage tracking.
highestPercentageReached = 0;

// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync(numberToCompute);
}
private void cancelAsyncButton_Click(System.Object sender, System.EventArgs e)
{
// Cancel the asynchronous operation.
this.backgroundWorker1.CancelAsync();
// Disable the Cancel button.
cancelAsyncButton.Enabled = false;
}
// This event handler is where the actual,
// potentially time-consuming work is done.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
e.Result = ComputeFibonacci((int)e.Argument, worker, e);
}

// This event handler deals with the results of the
// background operation.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// First, handle the case where an exception was thrown.
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
// Next, handle the case where the user canceled
// the operation.
// Note that due to a race condition in
// the DoWork event handler, the Cancelled
// flag may not have been set, even though
// CancelAsync was called.
resultLabel.Text = "Canceled";
}
else
{
// Finally, handle the case where the operation
// succeeded.
resultLabel.Text = e.Result.ToString();
}
// Enable the UpDown control.
this.numericUpDown1.Enabled = true;
// Enable the Start button.
startAsyncButton.Enabled = true;
// Disable the Cancel button.
cancelAsyncButton.Enabled = false;
}
// This event handler updates the progress bar.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}

// This is the method that does the actual work. For this
// example, it computes a Fibonacci number and
// reports progress as it does its work.
long ComputeFibonacci(int n, BackgroundWorker worker, DoWorkEventArgs e)
{
// The parameter n must be >= 0 and <= 91.
// Fib(n), with n > 91, overflows a long.
if ((n < 0) || (n > 91))
{
throw new ArgumentException("value must be >= 0 and <= 91", "n");
}
long result = 0;

// Abort the operation if the user has canceled.
// Note that a call to CancelAsync may have set
// CancellationPending to true just after the
// last invocation of this method exits, so this
// code will not have the opportunity to set the
// DoWorkEventArgs.Cancel flag to true. This means
// that RunWorkerCompletedEventArgs.Cancelled will
// not be set to true in your RunWorkerCompleted
// event handler. This is a race condition.
if (worker.CancellationPending)
{
e.Cancel = true;
}
else
{
if (n < 2)
{
result = 1;
}
else
{
result = ComputeFibonacci(n - 1, worker, e) + ComputeFibonacci(n - 2, worker, e);
}

// Report progress as a percentage of the total task.
int percentComplete = (int)((float)n / (float)numberToCompute * 100);
if (percentComplete > highestPercentageReached)
{
highestPercentageReached = percentComplete;
worker.ReportProgress(percentComplete);
}
}
return result;
}
}
}


分享到:
评论

相关推荐

    C#全能速查宝典

    分别介绍了C#语言基础、Windows窗体及常用控件、Windows高级控件、控件公共属性、方法及事件、数据库开发、文件、数据流与注册表、GDI+绘图技术和C#高级编程,共包含562个C#编程中常用的属性、方法、类和各种技术,...

    C#程序开发范例宝典(第2版).part02

    实例177 获取多媒体详细信息列表 253 5.2 MP3、WAV播放 254 实例178 带记忆功能的MP3播放器 254 实例179 自动播放的MP3播放器 257 实例180 学校体操定时音乐播放 258 实例181 播放系统自带的事件声音 259 实例...

    C#程序开发范例宝典(第2版).part08

    实例177 获取多媒体详细信息列表 253 5.2 MP3、WAV播放 254 实例178 带记忆功能的MP3播放器 254 实例179 自动播放的MP3播放器 257 实例180 学校体操定时音乐播放 258 实例181 播放系统自带的事件声音 259 实例...

    C#程序开发范例宝典(第2版).part12

    实例177 获取多媒体详细信息列表 253 5.2 MP3、WAV播放 254 实例178 带记忆功能的MP3播放器 254 实例179 自动播放的MP3播放器 257 实例180 学校体操定时音乐播放 258 实例181 播放系统自带的事件声音 259 实例...

    C#程序开发范例宝典(第2版).part13

    实例177 获取多媒体详细信息列表 253 5.2 MP3、WAV播放 254 实例178 带记忆功能的MP3播放器 254 实例179 自动播放的MP3播放器 257 实例180 学校体操定时音乐播放 258 实例181 播放系统自带的事件声音 259 实例...

Global site tag (gtag.js) - Google Analytics