Procédure pas à pas : exécution d'une opération en arrière-plan

Si vous avez une opération dont l'exécution va prendre beaucoup de temps et que vous ne souhaitez pas causer de retards dans votre interface utilisateur, vous pouvez utiliser la classe BackgroundWorker pour exécuter l'opération sur un autre thread.

Pour une liste complète du code utilisé dans cet exemple, consultez Comment : exécuter une opération en arrière-plan.

Notes

Les boîtes de dialogue et les commandes de menu qui s'affichent peuvent être différentes de celles qui sont décrites dans l'aide, en fonction de vos paramètres actifs ou de l'édition utilisée. Pour modifier vos paramètres, choisissez Importation et exportation de paramètres dans le menu Outils. Pour plus d'informations, consultez Utilisation des paramètres.

Pour exécuter une opération en arrière-plan

  1. Avec votre formulaire actif dans le Concepteur Windows Forms, faites glisser deux contrôles Button de la boîte à outils vers le formulaire, puis définissez les propriétés Name et Text des boutons en fonction du tableau suivant.

    Button

    Nom

    Texte

    button1

    startBtn

    Démarrer

    button2

    cancelBtn

    Cancel

  2. Ouvrez la boîte à outils, cliquez sur l'onglet Composants, puis faites glisser le composant BackgroundWorker sur votre formulaire.

    Le composant backgroundWorker1 apparaît dans la barre d'état des composants.

  3. Dans la fenêtre Propriétés, affectez à la propriété WorkerSupportsCancellation la valeur true.

  4. Dans la fenêtre Propriétés, cliquez sur le bouton Événements, puis double-cliquez sur les événements DoWork et RunWorkerCompleted pour créer des gestionnaires d'événements.

  5. Insérez votre code dont l'exécution prend beaucoup de temps dans le gestionnaire d'événements DoWork.

  6. Extrayez, de la propriété Argument du paramètre DoWorkEventArgs, tous les paramètres requis par l'opération.

  7. Assignez le résultat du calcul à la propriété Result de DoWorkEventArgs.

    Celui-ci sera accessible par le gestionnaire d'événements 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;
        }
    }
    
  8. Insérez le code pour récupérer le résultat de votre opération dans le gestionnaire d'événements 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);
        }
    }
    
  9. Implémentez la méthode 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;
    }
    
  10. Dans le Concepteur Windows Forms, doublez-cliquez sur startButton pour créer le gestionnaire d'événements Click.

  11. Appelez la méthode RunWorkerAsync dans le gestionnaire d'événements Click pour startButton.

    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);
    }
    
  12. Dans le Concepteur Windows Forms, doublez-cliquez sur cancelButton pour créer le gestionnaire d'événements Click.

  13. Appelez la méthode CancelAsync dans le gestionnaire d'événements Click pour cancelButton.

    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();
    }
    
  14. En haut du fichier, importez les espaces de noms System.ComponentModel et 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;
    
  15. Appuyez sur F6 pour générer la solution, puis sur CTRL+F5 pour exécuter l'application en dehors du débogueur.

Notes

Si vous appuyez sur F5 pour exécuter l'application sous le débogueur, l'exception levée dans la méthode TimeConsumingOperation est interceptée et affichée par le débogueur. Lorsque vous exécutez l'application en dehors du débogueur, BackgroundWorker gère l'exception et le met en cache dans la propriété Error de RunWorkerCompletedEventArgs.

  1. Cliquez sur le bouton Démarrer pour exécuter une opération asynchrone, puis cliquez sur le bouton Annuler pour arrêter une opération asynchrone en cours d'exécution.

    Le résultat de chaque opération est affiché dans un MessageBox.

Étapes suivantes

Voir aussi

Tâches

Comment : implémenter un formulaire qui utilise une opération d'arrière-plan

Comment : exécuter une opération en arrière-plan

Référence

BackgroundWorker

DoWorkEventArgs

Autres ressources

BackgroundWorker, composant