BackgroundWorker异步作业学习 2010-03-29 C# 暂无评论 2322 次阅读 学习Thread的时候,发现了一个问题:如下代码,意在实现填充listbox的动作在新建的thread中工作,这样不至于出现UI“假死”现象。 看代码: ``` public void foo() { listBox1.Items.Clear(); for (int i = 0; i < 10000; i++) { listBox1.Items.Add(i.ToString()); } } private void button2_Click(object sender, EventArgs e) { Thread thread = new Thread(new ThreadStart(foo)); thread.Start(); } ``` 执行出现错误:正在访问的Control listbox1的线程并不是创建它的线程,也就是不一致(好像是这个意思),一查Msdn,才发现这样的作业方式是Unsafe的,原因说了一大堆。推荐的方式是首先判断两个ThreadID是否一致,如果不一致,采用委托的方式进行safe的编程。 ``` public delegate void Mydel(); public void foo() { if (listBox1.InvokeRequired) { Mydel del = new Mydel(foo); this.Invoke(del); } else { listBox1.Items.Clear(); for (int i = 0; i < 10000; i++) { listBox1.Items.Add(i.ToString()); } } } private void button2_Click(object sender, EventArgs e) { Thread thread = new Thread(new ThreadStart(foo)); thread.Start(); } ``` 不知道是我写的有问题,还是其他什么原因,总之这样是可以运行,但是好像不能达到我的目的。 于是就看到了BackgroundWorker 组件:(msdn定义)BackgroundWorker 類別可以讓您在個別的專用執行緒上執行作業。執行耗費時間的作業 (例如下載和資料庫異動) 時,可能會讓使用者介面 (UI) 看起來像是已經停止反應。當您想要讓 UI 有所反應,但卻又必須面臨與這類作業相關的長時間延遲現象時,BackgroundWorker 類別可以提供便利的方案。 若要設定背景作業,請加入 DoWork 事件的事件處理常式。在這個事件處理常式中呼叫耗時作業。若要啟動作業,請呼叫 RunWorkerAsync。若要接收進度更新的告知,請處理 ProgressChanged 事件。若要在作業完成時接收告知,請處理 RunWorkerCompleted 事件。 您必須小心,不要在 DoWork 事件處理常式中操作任何使用者介面物件。相反地,請透過 ProgressChanged 和 RunWorkerCompleted 事件,與使用者介面通訊。 看例子: ``` public double foo2() // 3.背景实际运算 { double result=0; Thread.Sleep(5000); for (int i = 0; i < 100000; i++) { result += i; } return result; } private void button3_Click(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); //1.开始异步作业,跳转DoWork事件 } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { this.progressBar1.Value = e.ProgressPercentage; //结合ProgressBar显示执行进度 } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { textBox1.Text = e.Result.ToString(); //4.将作业结果返回UI } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { e.Result= foo2(); //2.执行背景运算作业,并存储结果(注意,不能在这里与UI进行交互) } ``` 运行后,可以看到,执行期间,并不影响你在UI做其他的动作,真正实现了异步作业。 转自http://lyq888.blog.sohu.com/104965491.html 标签: C#, BackgroundWorker, asynchronous, assignments 本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。