逐步解說:在背景執行作業
如果您有要花費較長時間才能完成的作業,但您不想導致使用者介面發生延遲,就可以使用 BackgroundWorker 類別在另一個執行緒上執行該作業。
如需在此範例中使用的完整程式碼清單,請參閱 HOW TO:在背景執行作業。
![]() |
---|
根據您目前使用的設定或版本,您所看到的對話方塊與功能表指令可能會與 [說明] 中描述的不同。 若要變更設定,請從 [工具] 功能表中選取 [匯入和匯出設定]。 如需詳細資訊,請參閱 使用設定。 |
若要在背景執行作業
使您的表單成為 [Windows Form 設計工具] 中的現用表單,從 [工具箱] 拖曳兩個 Button 控制項到表單中,然後根據下表設定按鈕的 Name 和 Text 屬性。
Button
Name
Text
button1
startBtn
Start
button2
cancelBtn
Cancel
開啟 [工具箱],按一下 [元件] 索引標籤,然後將 BackgroundWorker 元件拖曳到表單上。
backgroundWorker1 元件隨即出現在 [元件匣] 上。
在 [屬性] 視窗中,將 WorkerSupportsCancellation 屬性設定為 true。
在 [屬性] 視窗中,按一下 [事件] 按鈕,再按兩下 DoWork 和 RunWorkerCompleted 事件以建立事件處理常式。
在 DoWork 事件處理常式中插入會耗費許多時間的程式碼。
從 DoWorkEventArgs 參數的 Argument 屬性中擷取這項作業所需的任何參數。
將計算的結果指派至 DoWorkEventArgs 的 Result 屬性。
RunWorkerCompleted 事件處理常式將可以使用這個結果。
Private Sub backgroundWorker1_DoWork( _ sender As Object, e As DoWorkEventArgs) _ Handles backgroundWorker1.DoWork ' Do not access the form's BackgroundWorker reference directly. ' Instead, use the reference provided by the sender parameter. Dim bw As BackgroundWorker = CType( sender, BackgroundWorker ) ' Extract the argument. Dim arg As Integer = Fix(e.Argument) ' Start the time-consuming operation. e.Result = TimeConsumingOperation(bw, arg) ' If the operation was canceled by the user, ' set the DoWorkEventArgs.Cancel property to true. If bw.CancellationPending Then e.Cancel = True End If End Sub
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { // Do not access the form's BackgroundWorker reference directly. // Instead, use the reference provided by the sender parameter. BackgroundWorker bw = sender as BackgroundWorker; // Extract the argument. int arg = (int)e.Argument; // Start the time-consuming operation. e.Result = TimeConsumingOperation(bw, arg); // If the operation was canceled by the user, // set the DoWorkEventArgs.Cancel property to true. if (bw.CancellationPending) { e.Cancel = true; } }
在 RunWorkerCompleted 事件處理常式中插入擷取結果的程式碼。
' This event handler demonstrates how to interpret ' the outcome of the asynchronous operation implemented ' in the DoWork event handler. Private Sub backgroundWorker1_RunWorkerCompleted( _ sender As Object, e As RunWorkerCompletedEventArgs) _ Handles backgroundWorker1.RunWorkerCompleted If e.Cancelled Then ' The user canceled the operation. MessageBox.Show("Operation was canceled") ElseIf (e.Error IsNot Nothing) Then ' There was an error during the operation. Dim msg As String = String.Format("An error occurred: {0}", e.Error.Message) MessageBox.Show(msg) Else ' The operation completed normally. Dim msg As String = String.Format("Result = {0}", e.Result) MessageBox.Show(msg) End If End Sub
// This event handler demonstrates how to interpret // the outcome of the asynchronous operation implemented // in the DoWork event handler. private void backgroundWorker1_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { // The user canceled the operation. MessageBox.Show("Operation was canceled"); } else if (e.Error != null) { // There was an error during the operation. string msg = String.Format("An error occurred: {0}", e.Error.Message); MessageBox.Show(msg); } else { // The operation completed normally. string msg = String.Format("Result = {0}", e.Result); MessageBox.Show(msg); } }
實作 TimeConsumingOperation 方法。
' This method models an operation that may take a long time ' to run. It can be cancelled, it can raise an exception, ' or it can exit normally and return a result. These outcomes ' are chosen randomly. Private Function TimeConsumingOperation( _ bw As BackgroundWorker, _ sleepPeriod As Integer) As Integer Dim result As Integer = 0 Dim rand As New Random() While Not bw.CancellationPending Dim [exit] As Boolean = False Select Case rand.Next(3) ' Raise an exception. Case 0 Throw New Exception("An error condition occurred.") Exit While ' Sleep for the number of milliseconds ' specified by the sleepPeriod parameter. Case 1 Thread.Sleep(sleepPeriod) Exit While ' Exit and return normally. Case 2 result = 23 [exit] = True Exit While Case Else Exit While End Select If [exit] Then Exit While End If End While Return result End Function
// This method models an operation that may take a long time // to run. It can be cancelled, it can raise an exception, // or it can exit normally and return a result. These outcomes // are chosen randomly. private int TimeConsumingOperation( BackgroundWorker bw, int sleepPeriod ) { int result = 0; Random rand = new Random(); while (!bw.CancellationPending) { bool exit = false; switch (rand.Next(3)) { // Raise an exception. case 0: { throw new Exception("An error condition occurred."); break; } // Sleep for the number of milliseconds // specified by the sleepPeriod parameter. case 1: { Thread.Sleep(sleepPeriod); break; } // Exit and return normally. case 2: { result = 23; exit = true; break; } default: { break; } } if( exit ) { break; } } return result; }
在 [Windows Form 設計工具] 中按兩下 startButton 以建立 Click 事件處理常式。
為 startButton 呼叫 Click 事件處理常式中的 RunWorkerAsync 方法。
Private Sub startButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles startBtn.Click Me.backgroundWorker1.RunWorkerAsync(2000) End Sub
private void startBtn_Click(object sender, EventArgs e) { this.backgroundWorker1.RunWorkerAsync(2000); }
在 [Windows Form 設計工具] 中按兩下 cancelButton 以建立 Click 事件處理常式。
為 cancelButton 呼叫 Click 事件處理常式中的 CancelAsync 方法。
Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cancelBtn.Click Me.backgroundWorker1.CancelAsync() End Sub
private void cancelBtn_Click(object sender, EventArgs e) { this.backgroundWorker1.CancelAsync(); }
在檔案的頂端,匯入 System.ComponentModel 和 System.Threading 命名空間。
Imports System Imports System.ComponentModel Imports System.Drawing Imports System.Threading Imports System.Windows.Forms
using System; using System.ComponentModel; using System.Drawing; using System.Threading; using System.Windows.Forms;
按 F6 建置方案,然後按 CTRL-F5 在偵錯工具外部執行應用程式。
![]() |
---|
如果您按 F5 在偵錯工具內部執行應用程式,偵錯工具會攔截並顯示在 TimeConsumingOperation 方法中所引發的例外狀況。 當您在偵錯工具內部執行應用程式時,BackgroundWorker 會處理例外狀況,並在 RunWorkerCompletedEventArgs 的 Error 屬性中將其攔截。 |
按一下 [開始] 按鈕以執行非同步作業,然後按一下 [取消] 按鈕以停止執行中的非同步作業。
每個作業的結果會顯示於 MessageBox。
後續步驟
實作一個可以回報非同步作業進度的表單。 如需詳細資訊,請參閱 HOW TO:實作使用背景作業的表單。
實作一個支援元件非同步模式的類別。 如需詳細資訊,請參閱實作事件架構非同步模式。