在我們的程序中,經常會有一些耗時較長的運算,為了保證用戶體驗,不引起界面不響應,我們一般會采用多線程操作,讓耗時操作在后台完成,完成后再進行處理或給出提示,在運行中,也會時時去刷新界面上的進度條等顯示元,必要進,還要控制后台線程中斷當前操作。
以前,類似的應用會比較麻煩,需要寫的代碼較多,也很容易出現異常。在 .net中,提供了一個組件 backgroundworker就是專門解決這個問題的。
使用這個組件其實非常簡單,例如,我們做一個類似如下界面的進度條的小例子,在后台線程中進行耗時運算,同時刷新界面上的滾動條和提示信息,運行結束后,彈出處理結果。
在界面上拖入backgroundWorker組件,並響應其三個事件。
代碼如下:
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;
namespace 多線程小例子
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//這里就是通過響應消息,來處理界面的顯示工作
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
this.label1.Text = e.UserState.ToString();
this.label1.Update();
}
//這里是后台工作完成后的消息處理,可以在這里進行后續的處理工作。
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 類,跟傳統用法沒什么大區別,也挺好用的。具體介紹請看另一篇文章。
網易公司版權所有 ©1997-2016
評論
很不錯,別的教程都太難懂,就看到你講的很簡明扼要,把總體的流程講的很清楚。
您肯定是很有經驗的程序員吧?我感覺現在C#的書要不就是邏輯上講的不是很清晰,要不就是講的太簡單,需要的東西很多沒有講到。
很感謝。
這樣就能用了
除了那個“取消”不能正常使用,其他的都能用
還是很謝謝作者的,我的一個程序很慢,用了他的方法(改寫),一兩秒就跑完了
大家用的時候要在界面加入下面的東西:
一個 BackgroundWorker 一個lable 一個progressBar 還有三個button
記得 和程序中的名稱 和對應的方法名 一致
很好
開始按鈕中加個這個合適一些
if (this.backgroundWorker1.IsBusy)
{
return;
}