Exemplarische Vorgehensweise: Ausführen eines Vorgangs im Hintergrund

Wenn die Ausführung eines Vorgangs sehr lange dauert und Sie Verzögerungen in der Benutzeroberfläche vermeiden möchten, können Sie den Vorgang mithilfe der BackgroundWorker-Klasse in einem anderen Thread ausführen.

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

Hinweis

Die angezeigten Dialogfelder und Menübefehle können je nach den aktiven Einstellungen oder der verwendeten Version von den in der Hilfe beschriebenen abweichen. Wählen Sie im Menü Extras die Option Einstellungen importieren und exportieren aus, um die Einstellungen zu ändern. Weitere Informationen finden Sie unter Visual Studio-Einstellungen.

So führen Sie einen Vorgang im Hintergrund aus

  1. Ziehen Sie, während das Formular im Windows Forms-Designer aktiv ist, zwei Button-Steuerelemente aus der Toolbox auf das Formular, und legen Sie dann die Name-Eigenschaft und die Text-Eigenschaft der Schaltflächen entsprechend der folgenden Tabelle fest.

    Schaltfläche Name Text

    button1

    startBtn

    Start

    button2

    cancelBtn

    Cancel

  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 im Komponentenfach angezeigt.

  3. Klicken Sie im Eigenschaftenfenster auf die Schaltfläche Ereignisse, und doppelklicken Sie dann auf das DoWork-Ereignis und das RunWorkerCompleted-Ereignis, um Ereignishandler zu erstellen.

  4. Fügen Sie den zeitaufwendigen Code in den DoWork-Ereignishandler ein.

  5. Extrahieren Sie alle vom Vorgang benötigten Parameter aus der Argument-Eigenschaft des DoWorkEventArgs-Parameters.

  6. Weisen Sie der Result-Eigenschaft von DoWorkEventArgs das Ergebnis der Berechnung zu.

    Dieses Ergebnis steht dem RunWorkerCompleted-Ereignishandler zur Verfügung.

    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;
        }
    }
    
  7. Fügen Sie Code ein, durch den das Ergebnis des Vorgangs im RunWorkerCompleted-Ereignishandler abgerufen wird.

    ' 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);
        }
    }
    
  8. 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 Function TimeConsumingOperation( _
    bw As BackgroundWorker, _
    sleepPeriod As Integer) As Integer
    
       Dim result As Integer = 0
    
       Dim rand As New Random()
    
       While Not Me.backgroundWorker1.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 (!this.backgroundWorker1.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;
    }
    
  9. Doppelklicken Sie im Windows Forms-Designer auf startButton, um den Click-Ereignishandler zu erstellen.

  10. Rufen Sie die RunWorkerAsync-Methode im Click-Ereignishandler für startButton auf.

    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);
    }
    
  11. Doppelklicken Sie im Windows Forms-Designer auf cancelButton, um den Click-Ereignishandler zu erstellen.

  12. Rufen Sie die CancelAsync-Methode im Click-Ereignishandler für cancelButton auf.

    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);
    }
    
  13. Drücken Sie F6, um die Projektmappe zu erstellen, und dann STRG+F5, um die Anwendung außerhalb des Debuggers auszuführen.

Hinweis

Wenn Sie F5 drücken, um die Anwendung im Debugger auszuführen, wird die in der TimeConsumingOperation-Methode ausgelöste Ausnahme abgefangen und vom Debugger angezeigt. Wenn Sie die Anwendung außerhalb des Debuggers ausführen, behandelt BackgroundWorker die Ausnahme und fängt sie in der Error-Eigenschaft von RunWorkerCompletedEventArgs ab.

  1. Klicken Sie auf die Schaltfläche Start, um einen asynchronen Vorgang auszuführen, und dann auf die Schaltfläche Cancel, um einen laufenden asynchronen Vorgang anzuhalten.

    Das Ergebnis jedes Vorgangs wird in MessageBox angezeigt.

Nächste Schritte

Siehe auch

Aufgaben

Gewusst wie: Implementieren eines Formulars, das eine Hintergrundoperation verwendet
Gewusst wie: Ausführen eines Vorgangs im Hintergrund

Referenz

BackgroundWorker
DoWorkEventArgs

Weitere Ressourcen

BackgroundWorker-Komponente