C# - 非同步程式設計 - BackgroundWorker 類

IceCoke_lulu發表於2024-10-04

後臺執行緒,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 }

相關文章