在咱們的程序中,常常會有一些耗時較長的運算,爲了保證用戶體驗,不引發界面不響應,咱們通常會採用多線程操做,讓耗時操做在後臺完成,完成後再進行處理或給出提示,在運行中,也會時時去刷新界面上的進度條等顯示元,必要進,還要控制後臺線程中斷當前操做。程序員
之前,相似的應用會比較麻煩,須要寫的代碼較多,也很容易出現異常。在 .net中,提供了一個組件 backgroundworker就是專門解決這個問題的。多線程
使用這個組件其實很是簡單,例如,咱們作一個相似以下界面的進度條的小例子,在後臺線程中進行耗時運算,同時刷新界面上的滾動條和提示信息,運行結束後,彈出處理結果。函數
在界面上拖入backgroundWorker組件,並響應其三個事件。this
代碼以下:spa
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;.net
namespace 多線程小例子
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}線程
//這裏就是經過響應消息,來處理界面的顯示工做orm
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
this.label1.Text = e.UserState.ToString();
this.label1.Update();
}blog
//這裏是後臺工做完成後的消息處理,能夠在這裏進行後續的處理工做。進程
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("運算終於完成了");
}
//這裏,就是後臺進程開始工做時,調用工做函數的地方。你能夠把你現有的處理函數寫在這兒。
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
work(this.backgroundWorker1);
}
//真正的處理工做
private bool work(BackgroundWorker bk)
{
int tatle =10000;
for (int i = 0; i < tatle; i++)
{
if (bk.CancellationPending) //這裏判斷一下是否用戶要求取消後臺進行,並能夠儘早退出。
{
bk.ReportProgress(i, String.Format("當前值是 {0},操做被用戶申請中斷", i));
return false;
}
//處理的過程當中,經過這個函數,向主線程報告處理進度,最好是折算成百分比,與外邊的進度條的最大值必需要對應。這裏,我沒有折算,而是把界面線程的進度條最大值調整爲與這裏的總數一致。
bk.ReportProgress(i, String.Format("當前值是 {0} ", i));
}
return true;
}
private void button2_Click(object sender, EventArgs e)
{
//用戶要求取消時,就這樣處理一下。有時不太靈喔。
this.backgroundWorker1.CancelAsync();
}
private void button1_Click(object sender, EventArgs e)
{
//這一句,就是讓後臺工做開始。
this.backgroundWorker1.RunWorkerAsync();
}
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
通常的工做,就這樣的套路處理一下,基本就能夠工做了,若是多個線程之間還要交互,或是有共享數據等問題,.net C# 中仍是提供 System.Threading.Thread 類,跟傳統用法沒什麼大區別,也挺好用的。具體介紹請看另外一篇文章。