Genomgång: Köra en åtgärd i bakgrunden
Om du har en åtgärd som tar lång tid att slutföra och du inte vill orsaka fördröjningar i användargränssnittet kan du använda klassen BackgroundWorker för att köra åtgärden på en annan tråd.
En fullständig lista över koden som används i det här exemplet finns i How to: Run an Operation in the Background.
Kör en åtgärd i bakgrunden
När formuläret är aktivt i Windows Forms Designer i Visual Studio drar du två Button kontroller från Toolbox till formuläret och anger sedan
Name
och Text egenskaper för knapparna enligt följande tabell.Knapp Namn Text button1
startBtn
Starta button2
cancelBtn
Avbryt Öppna verktygslådan , klicka på fliken Komponenter och dra sedan komponenten BackgroundWorker till formuläret.
Komponenten
backgroundWorker1
visas i -komponentfältet.I fönstret Egenskaper anger du egenskapen WorkerSupportsCancellation till
true
.I fönstret Egenskaper klickar du på knappen Händelser och dubbelklickar sedan på händelserna DoWork och RunWorkerCompleted för att skapa händelsehanterare.
Infoga din tidskrävande kod i händelsehanteraren för DoWork.
Extrahera alla parametrar som krävs av åtgärden från egenskapen Argument för parametern DoWorkEventArgs.
Tilldela resultatet av beräkningen till egenskapen Result för DoWorkEventArgs.
Detta kommer att vara tillgängligt för RunWorkerCompleted:s händelsehanterare.
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
Infoga kod för att hämta resultatet av åtgärden i RunWorkerCompleted händelsehanterare.
// 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
Implementera metoden
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
I Windows Forms Designer dubbelklickar du på
startButton
för att skapa Click händelsehanterare.Anropa RunWorkerAsync-metoden i händelsehanteraren för Click för
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
I Windows Forms Designer dubbelklickar du på
cancelButton
för att skapa Click händelsehanterare.Anropa CancelAsync-metoden i händelsehanteraren för Click för
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
Längst upp i filen importerar du namnrymderna System.ComponentModel och 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
Tryck på F6 för att skapa lösningen och tryck sedan på Ctrl+F5 för att köra programmet utanför felsökningsprogrammet.
Notis
Om du trycker på F5- för att köra programmet under felsökningsprogrammet fångas undantaget som anges i metoden
TimeConsumingOperation
och visas av felsökningsprogrammet. När du kör programmet utanför felsökningsprogrammet hanterar BackgroundWorker undantaget och cachelagrar det i egenskapen Error för RunWorkerCompletedEventArgs.Klicka på knappen Starta för att köra en asynkron åtgärd och klicka sedan på knappen Avbryt för att stoppa en asynkron åtgärd som körs.
Resultatet av varje åtgärd visas i en MessageBox.
Nästa steg
Implementera ett formulär som rapporterar förlopp när en asynkron åtgärd fortsätter. Mer information finns i Så här implementerar du ett formulär som använder en bakgrundsåtgärd.
Implementera en klass som stöder Asynkront mönster för komponenter. Mer information finns i Implementera det händelsebaserade asynkrona mönstret.
Se även
.NET Desktop feedback