Esporta (0) Stampa
Espandi tutto
Il presente articolo è stato tradotto manualmente. Passare il puntatore sulle frasi nell'articolo per visualizzare il testo originale.
Traduzione
Originale

Classe BackgroundWorker

Esegue un'operazione in un thread separato.

Spazio dei nomi:  System.ComponentModel
Assembly:  System (in System.dll)

[HostProtectionAttribute(SecurityAction.LinkDemand, SharedState = true)]
public class BackgroundWorker : Component

Il tipo BackgroundWorker espone i seguenti membri.

  NomeDescrizione
Metodo pubblicoBackgroundWorkerInizializza una nuova istanza della classe BackgroundWorker.
In alto

  NomeDescrizione
Proprietà pubblicaCancellationPendingOttiene un valore che indica se l'applicazione ha richiesto l'annullamento di un'operazione in background.
Proprietà protetta.CanRaiseEventsOttiene un valore che indica se il componente può generare un evento. (Ereditato da Component)
Proprietà pubblicaContainerOttiene il IContainer che contiene il Component. (Ereditato da Component)
Proprietà protetta.DesignModeOttiene un valore che indica se il Component si trova in modalità progettazione. (Ereditato da Component)
Proprietà protetta.EventsOttiene l'elenco dei gestori eventi allegati a questo Component. (Ereditato da Component)
Proprietà pubblicaIsBusyOttiene un valore che indica se BackgroundWorker sta eseguendo un'operazione asincrona.
Proprietà pubblicaSiteOttiene o imposta il ISite del Component. (Ereditato da Component)
Proprietà pubblicaWorkerReportsProgressOttiene o imposta un valore che indica se la classe BackgroundWorker è in grado di segnalare gli aggiornamenti dello stato.
Proprietà pubblicaWorkerSupportsCancellationOttiene o imposta un valore che indica se la classe BackgroundWorker supporta l'annullamento asincrono.
In alto

  NomeDescrizione
Metodo pubblicoCancelAsyncRichiede l'annullamento di un'operazione in background in attesa.
Metodo pubblicoCreateObjRefConsente di creare un oggetto che contiene tutte le informazioni rilevanti necessarie per la generazione del proxy utilizzato per effettuare la comunicazione con un oggetto remoto. (Ereditato da MarshalByRefObject)
Metodo pubblicoDispose()Libera tutte le risorse utilizzate da Component. (Ereditato da Component)
Metodo protettoDispose(Boolean)Rilascia le risorse non gestite utilizzate dall'oggetto Component ed eventualmente rilascia le risorse gestite. (Ereditato da Component)
Metodo pubblicoEquals(Object)Determina se l'oggetto Object specificato è uguale all'oggetto Object corrente. (Ereditato da Object)
Metodo protettoFinalizeLibera risorse non gestite ed esegue altre operazioni di pulitura prima che Component sia recuperato dalla procedura di Garbage Collection. (Ereditato da Component)
Metodo pubblicoGetHashCodeFunge da funzione hash per un determinato tipo. (Ereditato da Object)
Metodo pubblicoGetLifetimeServiceConsente di recuperare l'oggetto servizio di durata corrente per controllare i criteri di durata per l'istanza. (Ereditato da MarshalByRefObject)
Metodo protettoGetServiceConsente di restituire un oggetto che rappresenta un servizio fornito da Component o dal relativo Container. (Ereditato da Component)
Metodo pubblicoGetType Ottiene il Type dell'istanza corrente. (Ereditato da Object)
Metodo pubblicoInitializeLifetimeServiceConsente di ottenere un oggetto servizio di durata per il controllo dei criteri di durata per l'istanza. (Ereditato da MarshalByRefObject)
Metodo protettoMemberwiseClone() Crea una copia dei riferimenti dell'oggetto Object corrente. (Ereditato da Object)
Metodo protettoMemberwiseClone(Boolean)Crea una copia dei riferimenti dell'oggetto MarshalByRefObject corrente. (Ereditato da MarshalByRefObject)
Metodo protettoOnDoWorkGenera l'evento DoWork.
Metodo protettoOnProgressChangedGenera l'evento ProgressChanged.
Metodo protettoOnRunWorkerCompletedGenera l'evento RunWorkerCompleted.
Metodo pubblicoReportProgress(Int32)Genera l'evento ProgressChanged.
Metodo pubblicoReportProgress(Int32, Object)Genera l'evento ProgressChanged.
Metodo pubblicoRunWorkerAsync()Avvia l'esecuzione di un'operazione in background.
Metodo pubblicoRunWorkerAsync(Object)Avvia l'esecuzione di un'operazione in background.
Metodo pubblicoToStringRestituisce un oggetto String contenente il nome dell'oggetto Component, se presente. Non è consigliabile eseguire l'override di questo metodo. (Ereditato da Component)
In alto

  NomeDescrizione
Evento pubblicoDisposedSi verifica quando il componente viene eliminato da una chiamata al metodo Dispose. (Ereditato da Component)
Evento pubblicoDoWorkViene generato quando viene chiamato il metodo RunWorkerAsync .
Evento pubblicoProgressChangedViene generato quando viene chiamato il metodo ReportProgress .
Evento pubblicoRunWorkerCompletedViene generato quando l'operazione in background è stata annullata o ha generato un'eccezione.
In alto

La classe BackgroundWorker consente di eseguire un'operazione in un thread separato e dedicato. Durante l'esecuzione di operazioni impegnative come download e transazioni di database, è possibile che l'interfaccia utente sembri non rispondere. Quando si desidera un'interfaccia utente reattiva malgrado i notevoli ritardi associati a questo tipo di operazioni, la classe BackgroundWorker offre una soluzione adeguata.

Per eseguire un'operazione impegnativa in background, creare un oggetto BackgroundWorker e restare in attesa degli eventi che segnalano l'avanzamento e il completamento dell'operazione. È possibile creare la classe BackgroundWorker a livello di codice oppure trascinarla sul form in uso dalla scheda Componenti della Casella degli strumenti. Se si crea la classe BackgroundWorker in Progettazione Windows Form, essa verrà visualizzata nella Barra dei componenti e le sue proprietà nella finestra Proprietà.

Per impostare un'operazione in background, aggiungere un gestore eventi per l'evento DoWork. Chiamare l'operazione desiderata nel gestore eventi. Per avviare l'operazione, chiamare il metodo RunWorkerAsync. Per ricevere notifiche relative agli aggiornamenti dell'avanzamento, gestire l'evento ProgressChanged. Per ricevere una notifica al termine dell'operazione, gestire l'evento RunWorkerCompleted.

NotaNota

Evitare di modificare oggetti dell'interfaccia utente nel gestore eventi DoWork. Comunicare invece con l'interfaccia utente tramite gli eventi ProgressChanged e RunWorkerCompleted.

Gli eventi BackgroundWorker non sono sottoposti a marshalling sui limiti di AppDomain. Non è possibile utilizzare un componente BackgroundWorker per eseguire operazioni multithread in più di un oggetto AppDomain.

Se l'operazione in background richiede un parametro, chiamare il metodo RunWorkerAsync tramite il parametro. All'interno del gestore eventi di DoWork, è possibile estrarre il parametro dalla proprietà DoWorkEventArgs.Argument.

Per ulteriori informazioni su BackgroundWorker, vedere Procedura: eseguire un'operazione in background.

NotaNota

L'attributo HostProtectionAttribute applicato a questo tipo di membro dispone del seguente valore per la proprietà Resources: SharedState. L'oggetto HostProtectionAttribute non influisce sulle applicazioni desktop, che in genere vengono avviate facendo doppio clic sull'icona, digitando un comando oppure immettendo un URL in un browser. Per ulteriori informazioni, vedere la classe HostProtectionAttribute o programmazione per SQL Server e attributi di protezione host.

Nell'esempio di codice seguente vengono illustrate le nozioni di base relative alla classe BackgroundWorker per l'esecuzione asincrona di un'operazione dispendiosa in termini di tempo. Nella figura seguente è illustrato un esempio di output.

Esempio di BackgroundWorker semplice

Per provare questo codice, creare un'applicazione Windows Form. Aggiungere un controllo Label denominato resultLabel e due controlli Button denominati startAsyncButton e cancelAsyncButton. Creare i gestori eventi Click per entrambi i pulsanti. Nella scheda Componenti della casella degli strumenti aggiungere un componente BackgroundWorker denominato backgroundWorker1. Creare i gestori eventi DoWork, ProgressChanged e RunWorkerCompleted per l'oggetto BackgroundWorker. Nel codice per il form, sostituire il codice esistente con il codice riportato di seguito.


using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace BackgroundWorkerSimple
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }

        private void startAsyncButton_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy != true)
            {
                // Start the asynchronous operation.
                backgroundWorker1.RunWorkerAsync();
            }
        }

        private void cancelAsyncButton_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.WorkerSupportsCancellation == true)
            {
                // Cancel the asynchronous operation.
                backgroundWorker1.CancelAsync();
            }
        }

        // This event handler is where the time-consuming work is done.
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            for (int i = 1; i <= 10; i++)
            {
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    // Perform a time consuming operation and report progress.
                    System.Threading.Thread.Sleep(500);
                    worker.ReportProgress(i * 10);
                }
            }
        }

        // This event handler updates the progress.
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            resultLabel.Text = (e.ProgressPercentage.ToString() + "%");
        }

        // This event handler deals with the results of the background operation.
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                resultLabel.Text = "Canceled!";
            }
            else if (e.Error != null)
            {
                resultLabel.Text = "Error: " + e.Error.Message;
            }
            else
            {
                resultLabel.Text = "Done!";
            }
        }
    }
}


Nell'esempio di codice seguente viene illustrato l'utilizzo della classe BackgroundWorker per l'esecuzione di un'operazione impegnativa in modo asincrono. Nella figura seguente è illustrato un esempio di output.

Esempio di BackgroundWorker con calcolo della sequenza di Fibonacci

L'operazione calcola il numero di Fibonacci selezionato, segnala gli aggiornamenti dell'avanzamento durante il calcolo e consente l'annullamento di un calcolo in sospeso.


using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace BackgroundWorkerExample
{	
    public class FibonacciForm : System.Windows.Forms.Form
    {	
        private int numberToCompute = 0;
        private int highestPercentageReached = 0;

        private System.Windows.Forms.NumericUpDown numericUpDown1;
        private System.Windows.Forms.Button startAsyncButton;
        private System.Windows.Forms.Button cancelAsyncButton;
        private System.Windows.Forms.ProgressBar progressBar1;
        private System.Windows.Forms.Label resultLabel;
        private System.ComponentModel.BackgroundWorker backgroundWorker1;

        public FibonacciForm()
        {	
            InitializeComponent();

            InitializeBackgroundWorker();
        }

        // Set up the BackgroundWorker object by 
        // attaching event handlers. 
        private void InitializeBackgroundWorker()
        {
            backgroundWorker1.DoWork += 
                new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.RunWorkerCompleted += 
                new RunWorkerCompletedEventHandler(
            backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.ProgressChanged += 
                new ProgressChangedEventHandler(
            backgroundWorker1_ProgressChanged);
        }
	
        private void startAsyncButton_Click(System.Object sender, 
            System.EventArgs e)
        {
            // Reset the text in the result label.
            resultLabel.Text = String.Empty;

            // Disable the UpDown control until 
            // the asynchronous operation is done.
            this.numericUpDown1.Enabled = false;

            // Disable the Start button until 
            // the asynchronous operation is done.
            this.startAsyncButton.Enabled = false;

            // Enable the Cancel button while 
            // the asynchronous operation runs.
            this.cancelAsyncButton.Enabled = true;

            // Get the value from the UpDown control.
            numberToCompute = (int)numericUpDown1.Value;

            // Reset the variable for percentage tracking.
            highestPercentageReached = 0;

            // Start the asynchronous operation.
            backgroundWorker1.RunWorkerAsync(numberToCompute);
        }

        private void cancelAsyncButton_Click(System.Object sender, 
            System.EventArgs e)
        {   
            // Cancel the asynchronous operation.
            this.backgroundWorker1.CancelAsync();

            // Disable the Cancel button.
            cancelAsyncButton.Enabled = false;
        }

        // This event handler is where the actual,
        // potentially time-consuming work is done.
        private void backgroundWorker1_DoWork(object sender, 
            DoWorkEventArgs e)
        {   
            // Get the BackgroundWorker that raised this event.
            BackgroundWorker worker = sender as BackgroundWorker;

            // Assign the result of the computation
            // to the Result property of the DoWorkEventArgs
            // object. This is will be available to the 
            // RunWorkerCompleted eventhandler.
            e.Result = ComputeFibonacci((int)e.Argument, worker, e);
        }

        // This event handler deals with the results of the
        // background operation.
        private void backgroundWorker1_RunWorkerCompleted(
            object sender, RunWorkerCompletedEventArgs e)
        {
            // First, handle the case where an exception was thrown.
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                // Next, handle the case where the user canceled 
                // the operation.
                // Note that due to a race condition in 
                // the DoWork event handler, the Cancelled
                // flag may not have been set, even though
                // CancelAsync was called.
                resultLabel.Text = "Canceled";
            }
            else
            {
                // Finally, handle the case where the operation 
                // succeeded.
                resultLabel.Text = e.Result.ToString();
            }

            // Enable the UpDown control.
            this.numericUpDown1.Enabled = true;

            // Enable the Start button.
            startAsyncButton.Enabled = true;

            // Disable the Cancel button.
            cancelAsyncButton.Enabled = false;
        }

        // This event handler updates the progress bar.
        private void backgroundWorker1_ProgressChanged(object sender,
            ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
        }

        // This is the method that does the actual work. For this
        // example, it computes a Fibonacci number and
        // reports progress as it does its work.
        long ComputeFibonacci(int n, BackgroundWorker worker, DoWorkEventArgs e)
        {
            // The parameter n must be >= 0 and <= 91.
            // Fib(n), with n > 91, overflows a long.
            if ((n < 0) || (n > 91))
            {
                throw new ArgumentException(
                    "value must be >= 0 and <= 91", "n");
            }

            long result = 0;

            // Abort the operation if the user has canceled.
            // Note that a call to CancelAsync may have set 
            // CancellationPending to true just after the
            // last invocation of this method exits, so this 
            // code will not have the opportunity to set the 
            // DoWorkEventArgs.Cancel flag to true. This means
            // that RunWorkerCompletedEventArgs.Cancelled will
            // not be set to true in your RunWorkerCompleted
            // event handler. This is a race condition.

            if (worker.CancellationPending)
            {   
                e.Cancel = true;
            }
            else
            {   
                if (n < 2)
                {   
                    result = 1;
                }
                else
                {   
                    result = ComputeFibonacci(n - 1, worker, e) + 
                             ComputeFibonacci(n - 2, worker, e);
                }

                // Report progress as a percentage of the total task.
                int percentComplete = 
                    (int)((float)n / (float)numberToCompute * 100);
                if (percentComplete > highestPercentageReached)
                {
                    highestPercentageReached = percentComplete;
                    worker.ReportProgress(percentComplete);
                }
            }

            return result;
        }


		#region Windows Form Designer generated code
		
        private void InitializeComponent()
        {
            this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
            this.startAsyncButton = new System.Windows.Forms.Button();
            this.cancelAsyncButton = new System.Windows.Forms.Button();
            this.resultLabel = new System.Windows.Forms.Label();
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
            this.SuspendLayout();
            // 
            // numericUpDown1
            // 
            this.numericUpDown1.Location = new System.Drawing.Point(16, 16);
            this.numericUpDown1.Maximum = new System.Decimal(new int[] {
            91,
            0,
            0,
            0});
            this.numericUpDown1.Minimum = new System.Decimal(new int[] {
            1,
            0,
            0,
            0});
            this.numericUpDown1.Name = "numericUpDown1";
            this.numericUpDown1.Size = new System.Drawing.Size(80, 20);
            this.numericUpDown1.TabIndex = 0;
            this.numericUpDown1.Value = new System.Decimal(new int[] {
            1,
            0,
            0,
            0});
            // 
            // startAsyncButton
            // 
            this.startAsyncButton.Location = new System.Drawing.Point(16, 72);
            this.startAsyncButton.Name = "startAsyncButton";
            this.startAsyncButton.Size = new System.Drawing.Size(120, 23);
            this.startAsyncButton.TabIndex = 1;
            this.startAsyncButton.Text = "Start Async";
            this.startAsyncButton.Click += new System.EventHandler(this.startAsyncButton_Click);
            // 
            // cancelAsyncButton
            // 
            this.cancelAsyncButton.Enabled = false;
            this.cancelAsyncButton.Location = new System.Drawing.Point(153, 72);
            this.cancelAsyncButton.Name = "cancelAsyncButton";
            this.cancelAsyncButton.Size = new System.Drawing.Size(119, 23);
            this.cancelAsyncButton.TabIndex = 2;
            this.cancelAsyncButton.Text = "Cancel Async";
            this.cancelAsyncButton.Click += new System.EventHandler(this.cancelAsyncButton_Click);
            // 
            // resultLabel
            // 
            this.resultLabel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.resultLabel.Location = new System.Drawing.Point(112, 16);
            this.resultLabel.Name = "resultLabel";
            this.resultLabel.Size = new System.Drawing.Size(160, 23);
            this.resultLabel.TabIndex = 3;
            this.resultLabel.Text = "(no result)";
            this.resultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // progressBar1
            // 
            this.progressBar1.Location = new System.Drawing.Point(18, 48);
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.Size = new System.Drawing.Size(256, 8);
            this.progressBar1.Step = 2;
            this.progressBar1.TabIndex = 4;
            // 
            // backgroundWorker1
            // 
            this.backgroundWorker1.WorkerReportsProgress = true;
            this.backgroundWorker1.WorkerSupportsCancellation = true;
            // 
            // FibonacciForm
            // 
            this.ClientSize = new System.Drawing.Size(292, 118);
            this.Controls.Add(this.progressBar1);
            this.Controls.Add(this.resultLabel);
            this.Controls.Add(this.cancelAsyncButton);
            this.Controls.Add(this.startAsyncButton);
            this.Controls.Add(this.numericUpDown1);
            this.Name = "FibonacciForm";
            this.Text = "Fibonacci Calculator";
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
            this.ResumeLayout(false);

        }
		#endregion

        [STAThread]
        static void Main()
        {
            Application.Run(new FibonacciForm());
        }
    }
}


.NET Framework

Supportato in: 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supportato in: 4, 3.5 SP1

Windows 7, Windows Vista SP1 o versione successiva, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (componenti di base del server non supportati), Windows Server 2008 R2 (componenti di base del server supportati con SP1 o versione successiva), Windows Server 2003 SP2

.NET Framework non supporta tutte le versioni di ciascuna piattaforma. Per un elenco delle versioni supportate, vedere Requisiti di sistema di .NET Framework.

Qualsiasi membro static (Shared in Visual Basic) pubblico di questo tipo è thread-safe. I membri di istanza non sono garantiti come thread-safe.

date

Cronologia

Motivo

Settembre 2010

È stato aggiunto un semplice esempio di codice BackgroundWorker.

Commenti e suggerimenti dei clienti.

Aggiunte alla community

AGGIUNGI
Mostra:
© 2015 Microsoft