星期二 十二月 22, 2009 09:17
cSharp中BackgroundWorker的用法
线程同步中,还有一个比较流行的类<BackgroundWorker>.
BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。
若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。
若要设置后台操作,请为 DoWork 事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用 RunWorkerAsync。若要收到进度更新通知,请对 ProgressChanged 事件进行处理。若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。
下面这个例子,主要从这几个方面来谈 cancellation support and report progress。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.backgroundWorker1.WorkerSupportsCancellation = true;
this.backgroundWorker1.WorkerReportsProgress = true;
this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}
private void button1_Click(object sender, EventArgs e)
{
if (this.textBox1.Text != "" && this.textBox2.Text != "")
{
ab a = new ab(int.Parse(this.textBox1.Text), int.Parse(this.textBox2.Text));
this.backgroundWorker1.RunWorkerAsync(a);
}
}
private void button2_Click(object sender, EventArgs e)
{
this.backgroundWorker1.CancelAsync();
}
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
this.textBox3.Text = "Result :Canclled!";
this.progressBar1.Value = 100;
}
else if (e.Error != null)
{
MessageBox.Show("Error Details : " + (e.Error as Exception).ToString());
}
else
{
this.textBox3.Text = "Result :" + e.Result;
this.progressBar1.Value = 100;
}
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//do something here backgroundly.
for (int i = 0; i < this.progressBar1.Maximum; i++)
{
Thread.Sleep(50);
this.backgroundWorker1.ReportProgress(i);
if (this.backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
}
ab a = (ab)e.Argument;
e.Result = a.C;
}
}
class ab
{
private int _a;
public int A
{
get { return _a; }
set { _a = value; }
}
private int _b;
public int B
{
get { return _b; }
set { _b = value; }
}
public ab(int a,int b)
{
this._a = a;
this._b = b;
}
public int C
{
get { return _b + _a; }
}
}
- Category: csharp-note
- No Comments