Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Se si dispone di un'operazione che richiederà molto tempo e non si desidera causare ritardi nell'interfaccia utente, è possibile usare la classe BackgroundWorker per eseguire l'operazione su un altro thread.
Per un elenco completo del codice usato in questo esempio, vedere Procedura: Eseguire un'operazione in background.
Esegui un'operazione in background
Con il modulo attivo in Progettazione di Windows Forms in Visual Studio, trascinare due controlli Button dalla Toolbox al form e quindi impostare le proprietà
Name
e Text dei pulsanti in base alla tabella seguente.Pulsante Nome Testo button1
startBtn
Inizio button2
cancelBtn
Annulla Apri la casella degli strumenti , fai clic sulla scheda componenti e quindi trascina il componente BackgroundWorker sul modulo.
Il componente
backgroundWorker1
appare nel Vassoio Componenti .Nella finestra Proprietà, imposta la proprietà WorkerSupportsCancellation su
true
.Nella finestra Proprietà, fare clic sul pulsante Eventi e quindi fare doppio clic sugli eventi DoWork e RunWorkerCompleted per creare gestori di eventi.
Inserisci il tuo codice che richiede molto tempo nel gestore di eventi DoWork.
Estrarre tutti i parametri richiesti dall'operazione dalla proprietà Argument del parametro DoWorkEventArgs.
Assegnare il risultato del calcolo alla proprietà Result del DoWorkEventArgs.
Questo sarà disponibile per il gestore eventi RunWorkerCompleted.
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
Inserire il codice per recuperare il risultato dell'operazione nel gestore eventi RunWorkerCompleted.
// 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
Implementare il metodo
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
Nella progettazione di Windows Forms, fare doppio clic su
startButton
per creare il gestore eventi Click.Chiamare il metodo RunWorkerAsync nel gestore eventi Click per
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
Nella progettazione di Windows Forms, fare doppio clic su
cancelButton
per creare il gestore eventi Click.Chiamare il metodo CancelAsync nel gestore eventi Click per
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
Nella parte superiore del file importare gli spazi dei nomi 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
Premere F6 per compilare la soluzione e quindi premere CTRL+F5 per eseguire l'applicazione all'esterno del debugger.
Annotazioni
Se si preme F5 per eseguire l'applicazione nel debugger, l'eccezione generata nel metodo
TimeConsumingOperation
viene intercettata e visualizzata dal debugger. Quando si esegue l'applicazione all'esterno del debugger, l'BackgroundWorker gestisce l'eccezione e la memorizza nella cache nella proprietà Error del RunWorkerCompletedEventArgs.Fare clic sul pulsante avvia
per eseguire un'operazione asincrona e quindi sul pulsante annulla per arrestare un'operazione asincrona in esecuzione. Il risultato di ciascuna operazione viene visualizzato in un MessageBox.
Passaggi successivi
Implementare un modulo che segnala lo stato di avanzamento durante l'esecuzione di un'operazione asincrona. Per ulteriori informazioni, consultare Come implementare un modulo che utilizza un'operazione in background.
Implementare una classe che supporta il modello asincrono per i componenti. Per altre informazioni, vedere Implementazione del modello asincrono basato su eventi.
Vedere anche
.NET Desktop feedback