後臺執行緒,BackgroundWorker
類用於建立一個執行緒,在後臺持續執行以完成某項工作,並不時地與主執行緒通訊。
BackgroundWorker
類的屬性,方法與事件。
屬性:
WorkerReportsProgress
:設定後臺任務是否可以把它的進度彙報給主執行緒。WorkerSupportsCancellation
:是否支援從主執行緒取消。IsBusy
:檢查後臺任務是否正在執行。CancellationPending
:每隔一段時間會檢查該屬性是否停止處理。
事件:
DoWork
- 在後臺執行緒開始時觸發。ProgressChanged
- 後臺任務彙報進度時觸發。RunWorkerCompleted
- 後臺工作執行緒退出時觸發。
方法:
RunWorkerAsync()
- 獲取後臺執行緒並執行 DoWork 事件處理程式。CancelAsync()
- 設定CancellationPending
屬性為true。DoWork()
- 事件處理程式希望向主執行緒序彙報進度的時候,呼叫 ReportProgress 方法。
1 namespace WpfApp1 2 { 3 /// <summary> 4 /// MainWindow.xaml 的互動邏輯 5 /// </summary> 6 public partial class MainWindow : Window 7 { 8 BackgroundWorker bgWorker = new BackgroundWorker(); 9 public MainWindow() 10 { 11 InitializeComponent(); 12 // 初始化 13 bgWorker.WorkerReportsProgress = true; 14 bgWorker.WorkerSupportsCancellation = true; 15 16 // 事件註冊 17 bgWorker.DoWork += DoWork_Handler; 18 bgWorker.ProgressChanged += ProgressChanged_Handler; 19 bgWorker.RunWorkerCompleted += RunWorkerCompleted_Handler; 20 } 21 22 private void RunWorkerCompleted_Handler(object sender, RunWorkerCompletedEventArgs e) 23 { 24 progressBar.Value = 0; 25 if (e.Cancelled) 26 MessageBox.Show("Process was cancelled.", "Process Cancelled"); 27 else 28 MessageBox.Show("Process completed normally.", "Process Completed"); 29 } 30 31 private void ProgressChanged_Handler(object sender, ProgressChangedEventArgs e) 32 { 33 // 設定進度條值 34 progressBar.Value = e.ProgressPercentage; 35 } 36 37 private void DoWork_Handler(object sender, DoWorkEventArgs e) 38 { 39 BackgroundWorker worker = sender as BackgroundWorker; 40 41 for (int i = 0; i <= 10; i++) 42 { 43 // 迴圈判斷 CancellationPending 是否為true。 44 if (worker.CancellationPending) 45 { 46 e.Cancel = true; 47 break; 48 } 49 else 50 { 51 // 觸發主執行緒 ProgressChanged 52 worker.ReportProgress(i * 10); 53 Thread.Sleep(250); 54 } 55 56 } 57 } 58 59 private async void btnProcess_Click(object sender, RoutedEventArgs e) 60 { 61 // 判斷當前後臺執行緒是否執行 62 if (!bgWorker.IsBusy) 63 // 呼叫方法啟動後臺執行緒,並觸發 DoWork 事件 64 bgWorker.RunWorkerAsync(); 65 } 66 67 private void btnCancel_Click(object sender, RoutedEventArgs e) 68 { 69 // 設定物件 CancelltionPending 為true; 70 bgWorker.CancelAsync(); 71 } 72 } 73 }