BackgroundWorker异步作业学习

学习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

0 Comments
Leave a Reply

Time limit is exhausted. Please reload the CAPTCHA.