System.Threading.Thread.Sleep相信各位Winform的程式員都知道是什麼,就是停止運作一定的時間,但作為一個已進化的菜鳥,不能夠在正常情況可使用,最好是在BackgroundWorker內用,就能夠神不知鬼不覺,因為當你不在BackgroundWorker內使用,該死的界面就會顯示(Not Responding)的字句,客戶就會走來找你,問是不是死機啊‧‧‧以下是一個簡單的例子。
1‧創建一個WINFORM界面,並新增4個Control─label1、button1、toolStripProgressBar1、backgroundworker1
*backgroundworker1不是User Interface*
2‧background新增Event Handler
WorkerReportsProgress一定要set成true,否則不能加入ProgressChanged Event。
this.backgroundWorker1.WorkerReportsProgress = true;
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
3‧ProgressChanged Event
主要是紀錄進度,除了toolStripProgressBar,toolStripLabel也是能夠更改的。
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// The progress percentage is a property of e
toolStripProgressBar1.Value = e.ProgressPercentage;
}
4‧DoWork Event
DoWork這裡會轉換label1的文字,ProgressBar亦會紀錄進度,Thread.Sleep在這裡使用。
在function內接觸Control類的,需要加入Invoke(Action),才可運行,否則會彈出跨線程錯誤。
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Args arg = (Args)e.Argument;
string a = arg.a;
string b = arg.b;
backgroundWorker1.ReportProgress(0);
label1.Invoke(new Action(() => { label1.Text = b; }));
backgroundWorker1.ReportProgress(30);
Thread.Sleep(1000);
backgroundWorker1.ReportProgress(60);
label1.Invoke(new Action(() => { label1.Text = a; }));
backgroundWorker1.ReportProgress(100);
Thread.Sleep(1000);
backgroundWorker1.ReportProgress(0);
button1.Invoke((Action)(() => button1.Enabled = true));
}
5‧Args Class
在DoWork拿取Control的數值、文字是比較困難的,最好的方法是由外面掉Parameter入DoWork Function,所以先創建一個Class。
簡簡單單,看得明白就好。
internal class Args
{
internal string a { get; set; }
internal string b { get; set; }
}
5‧Button1 Action
Button1用來啟動BackgroundWorker,而且將剛才的Class放入DoWork這個Function裡面。
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
var args = new Args() { a = "YES", b = "NO" };
backgroundWorker1.RunWorkerAsync(args);
}
6‧結果
運行時可以見到label1由"No"變成"Yes",而ProgressBar亦會上升,為時大約5秒,而且UI不會出現Not Responding字樣,所以成功了。
這個Backgroundworker、progressbar的進階教學也完結了,多謝各位。