Exemplarische Vorgehensweise: Ausführen eines Vorgangs im Hintergrund
Aktualisiert: November 2007
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
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
Ö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.
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.
Fügen Sie den zeitaufwendigen Code in den DoWork-Ereignishandler ein.
Extrahieren Sie alle vom Vorgang benötigten Parameter aus der Argument-Eigenschaft des DoWorkEventArgs-Parameters.
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; } }
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); } }
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 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; }
Doppelklicken Sie im Windows Forms-Designer auf startButton, um den Click-Ereignishandler zu erstellen.
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); }
Doppelklicken Sie im Windows Forms-Designer auf cancelButton, um den Click-Ereignishandler zu erstellen.
Rufen Sie die CancelAsync-Methode im Click-Ereignishandler für cancelButton auf.
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(); }
Importieren Sie oben in der Datei den System.ComponentModel-Namespace und den System.Threading-Namespace.
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;
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. |
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
Implementieren Sie ein Formular, durch das der Status eines asynchronen Vorgangs während der Ausführung gemeldet wird. Weitere Informationen finden Sie unter Gewusst wie: Implementieren eines Formulars, das eine Hintergrundoperation verwendet.
Implementieren Sie eine Klasse, die das asynchrone Muster für Komponenten unterstützt. Weitere Informationen finden Sie unter Implementieren des ereignisbasierten asynchronen Entwurfsmusters.
Siehe auch
Aufgaben
Gewusst wie: Implementieren eines Formulars, das eine Hintergrundoperation verwendet
Gewusst wie: Ausführen eines Vorgangs im Hintergrund