星期二 十二月 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