Passo a passo: executando uma operação em segundo plano

Se você tiver uma operação que levará muito tempo para ser concluída e não quiser causar atrasos na interface do usuário, poderá usar a classe para executar a BackgroundWorker operação em outro thread.

Para obter uma listagem completa do código usado neste exemplo, consulte Como executar uma operação em segundo plano.

Executar uma operação em segundo plano

  1. Com o formulário ativo no Windows Forms Designer no Visual Studio, arraste dois Button controles da caixa de ferramentas para o formulário e, em seguida, defina as Name propriedades e Text dos botões de acordo com a tabela a seguir.

    Botão Nome Texto
    button1 startBtn Iniciar
    button2 cancelBtn Cancelar
  2. Abra a Caixa de Ferramentas, clique na guia Componentes e arraste o componente para o BackgroundWorkerformulário.

    O componente backgroundWorker1 aparece na Bandeja de Componentes.

  3. Na janela Propriedades, defina a propriedade WorkerSupportsCancellation como true.

  4. Na janela Propriedades, clique no botão Eventos e, em seguida, clique duas vezes nos DoWork eventos e RunWorkerCompleted para criar manipuladores de eventos.

  5. Insira seu código demorado no DoWork manipulador de eventos.

  6. Extraia quaisquer parâmetros exigidos pela operação da Argument propriedade do DoWorkEventArgs parâmetro.

  7. Atribua o resultado da computação à Result propriedade do DoWorkEventArgs.

    Isso estará disponível para o manipulador de RunWorkerCompleted eventos.

    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. Insira o código para recuperar o resultado da operação no RunWorkerCompleted manipulador de eventos.

    // 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. Implementar o método de 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 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. No Windows Forms Designer, clique startButton duas vezes para criar o manipulador de Click eventos.

  11. Chame Click o RunWorkerAsync método no manipulador de eventos para startButton.

    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. No Windows Forms Designer, clique cancelButton duas vezes para criar o manipulador de Click eventos.

  13. Chame Click o CancelAsync método no manipulador de eventos para cancelButton.

    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. Na parte superior do arquivo, importe os namespaces System.ComponentModel e 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. Pressione F6 para criar a solução e, em seguida, pressione Ctrl+F5 para executar o aplicativo fora do depurador.

    Observação

    Se você pressionar F5 para executar o aplicativo no depurador, a exceção gerada no TimeConsumingOperation método será capturada e exibida pelo depurador. Quando você executa o aplicativo fora do depurador, o manipula a exceção e a armazena BackgroundWorker em cache na Error propriedade do RunWorkerCompletedEventArgs.

  16. Clique no botão Iniciar para executar uma operação assíncrona e, em seguida, no botão Cancelar para interromper uma operação assíncrona em execução.

    O resultado de cada operação é exibido em um MessageBoxarquivo .

Próximas etapas

Confira também