Exemplarische Vorgehensweise: Ausführen eines Vorgangs im Hintergrund

Gibt es einen Vorgang, der bis zu seinem Abschluss eine lange Zeit in Anspruch nimmt, und Sie möchten keine Verzögerungen in der Benutzeroberfläche verursachen, können Sie die BackgroundWorker-Klasse dazu verwenden, den Vorgang über einen anderen Thread auszuführen.

Eine vollständige Auflistung des in diesem Beispiel verwendeten Codes finden Sie unter Gewusst wie: Ausführen eines Vorgangs im Hintergrund.

Ausführen eines Vorgangs im Hintergrund

  1. Ziehen Sie mit dem Formular, das im Windows Forms-Designer in Visual Studio aktiv ist, zwei Button-Steuerelemente aus der Toolbox in das Formular, und legen Sie dann die Eigenschaften Name und Text der Schaltflächen gemäß der folgenden Tabelle fest.

    Schaltfläche Name Text
    button1 startBtn Starten
    button2 cancelBtn Abbrechen
  2. Öffnen Sie die Toolbox, klicken Sie auf die Registerkarte Komponenten, und ziehen Sie dann die BackgroundWorker-Komponente auf das Formular.

    Die backgroundWorker1-Komponente wird in der Komponentenleiste angezeigt.

  3. Legen Sie im Fenster Eigenschaften die Eigenschaft WorkerSupportsCancellation auf truefest.

  4. Klicken Sie im Fenster Eigenschaften auf die Schaltfläche Ereignisse, und doppelklicken Sie dann auf die Ereignisse DoWork und RunWorkerCompleted, um Ereignishandler zu erstellen.

  5. Fügen Sie Ihren zeitverbrauchenden Code in den DoWork-Ereignishandler ein.

  6. Extrahieren Sie alle Parameter, die vom Vorgang aus der Eigenschaft Argument des DoWorkEventArgs-Parameters benötigt werden.

  7. Weisen Sie das Ergebnis der Berechnung der Eigenschaft Result des DoWorkEventArgs zu.

    Dies wird für den RunWorkerCompleted-Ereignishandler verfügbar sein.

    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;
        }
    }
    
    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   
    
  8. Fügen Sie Code zum Abrufen des Ergebnisses Ihres Vorgangs im RunWorkerCompleted-Ereignishandler ein.

    // 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);
        }
    }
    
    ' 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   
    
  9. Implementieren Sie die TimeConsumingOperation-Methode.

    // 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;
    }
    
    ' 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
    
  10. Doppelklicken Sie im Windows Forms-Designer auf startButton, um den Click-Ereignishandler zu erstellen.

  11. Rufen Sie die RunWorkerAsync-Methode im Click-Ereignishandler zum startButton auf.

    private void startBtn_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync(2000);
    }
    
    Private Sub startButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles startBtn.Click
        Me.backgroundWorker1.RunWorkerAsync(2000)
    End Sub
    
  12. Doppelklicken Sie im Windows Forms-Designer auf cancelButton, um den Click-Ereignishandler zu erstellen.

  13. Rufen Sie die CancelAsync-Methode im Click-Ereignishandler zum cancelButton auf.

    private void cancelBtn_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.CancelAsync();
    }
    
    Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cancelBtn.Click
        Me.backgroundWorker1.CancelAsync()
    End Sub
    
  14. Importieren Sie oben in der Datei die Namespaces „System.ComponentModel“ und „System.Threading“.

    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;
    
    Imports System.ComponentModel
    Imports System.Drawing
    Imports System.Threading
    Imports System.Windows.Forms
    
  15. Drücken Sie F6, um die Lösung zu erstellen, und dann STRG+F5, um die Anwendung außerhalb des Debuggers auszuführen.

    Hinweis

    Wenn Sie F5 drücken, um die Anwendung unter dem Debugger auszuführen, wird die Ausnahme, die in der TimeConsumingOperation-Methode ausgelöst wird, erfasst und vom Debugger angezeigt. Wenn Sie die Anwendung außerhalb des Debuggers ausführen, bearbeitet BackgroundWorker die Ausnahme und speichert sie in der Error-Eigenschaft des RunWorkerCompletedEventArgs zwischen.

  16. Klicken Sie auf die Schaltfläche Start, um einen asynchronen Vorgang auszuführen, und klicken Sie dann auf die Schaltfläche Abbrechen, um einen gerade ausgeführten asynchronen Vorgang zu beenden.

    Das Ergebnis jedes Vorgangs wird in einem MessageBox-Steuerelement angezeigt.

Nächste Schritte

Weitere Informationen