非同步執行緒實做方法其實不難,首先要加入一個BackgroundWorker元件
在程式載入時我們就應該支援『非同步取消執行緒』,『可回報目前進度』其實要看使用者的需求
//支援非同步取消 backgroundWorker1.WorkerSupportsCancellation = true; //可報告目前進度 backgroundWorker1.WorkerReportsProgress = true;
那執行緒的工作應該放在哪個事件中呢?就放在DoWork裡面
有啟動可回報進度的使用者可以實做ProgressChanged事件,在事件裡去處理
RunWorkerCompleted事件裡則可以去處理到取消、錯誤以及完成時會在觸發哪些事件
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 testTheard { public partial class Form1 : Form { public Form1() { InitializeComponent(); //支援非同步取消 backgroundWorker1.WorkerSupportsCancellation = true; //可報告目前進度 backgroundWorker1.WorkerReportsProgress = true; progressBar1.Minimum = 0; progressBar1.Maximum = 50; progressBar1.Value = 0; buttonStop.Enabled = false; buttonStart.Enabled = true; } private void buttonStart_Click(object sender, EventArgs e) { buttonStart.Enabled = false; buttonStop.Enabled = true; //當執行緒不忙碌時 if (backgroundWorker1.IsBusy != true) { //開始作業 backgroundWorker1.RunWorkerAsync(); } } private void buttonStop_Click(object sender, EventArgs e) { buttonStop.Enabled = false; buttonStart.Enabled = true; //當使用非同步時 if (backgroundWorker1.WorkerSupportsCancellation == true) { //取消非同步 backgroundWorker1.CancelAsync(); } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; for (int i = 1; i <= 25; i++) { //如果有取消訊號 if (worker.CancellationPending == true) { //取消該事件並跳出迴圈 e.Cancel = true; break; } else { //0.5秒執行一次 System.Threading.Thread.Sleep(500); //回報進度=i*2 worker.ReportProgress(i * 2); } } } //當非同步執行緒在執行時 private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //如果取消 if (e.Cancelled == true) { MessageBox.Show("Canceled!"); } //如果錯誤 else if (e.Error != null) { MessageBox.Show("Error: " + e.Error.Message); } //如果完成 else { MessageBox.Show("Done!"); progressBar1.Value = 0; buttonStop.Enabled = false; buttonStart.Enabled = true; } } } }
參考資料:
http://support.microsoft.com/kb/315582/zh-tw
http://msdn.microsoft.com/zh-tw/library/2e08f6yc(v=vs.80).aspx
http://msdn.microsoft.com/zh-tw/library/windows/apps/hh452713.aspx
http://www.dotblogs.com.tw/kirkchen/archive/2010/12/28/20435.aspx
http://msdn.microsoft.com/zh-tw/library/system.componentmodel.backgroundworker.aspx
http://msdn.microsoft.com/zh-tw/library/system.componentmodel.backgroundworker.progresschanged.aspx