C# Language
BackgroundWorker
Recherche…
Syntaxe
bgWorker.CancellationPending //returns whether the bgWorker was cancelled during its operation
bgWorker.IsBusy //returns true if the bgWorker is in the middle of an operation
bgWorker.ReportProgress(int x) //Reports a change in progress. Raises the "ProgressChanged" event
bgWorker.RunWorkerAsync() //Starts the BackgroundWorker by raising the "DoWork" event
bgWorker.CancelAsync() //instructs the BackgroundWorker to stop after the completion of a task.
Remarques
L'exécution d'opérations de longue durée au sein du thread d'interface utilisateur peut entraîner le blocage de votre application, apparaissant à l'utilisateur comme ayant cessé de fonctionner. Il est préférable que ces tâches soient exécutées sur un thread d'arrière-plan. Une fois terminée, l'interface utilisateur peut être mise à jour.
Apporter des modifications à l'interface utilisateur pendant l'opération BackgroundWorker nécessite d'appeler les modifications apportées au thread d'interface utilisateur, généralement à l'aide de la méthode Control.Invoke sur le contrôle que vous mettez à jour. Si vous négligez de le faire, votre programme lancera une exception.
Le BackgroundWorker est généralement utilisé uniquement dans les applications Windows Forms. Dans les applications WPF, les tâches permettent de décharger le travail sur les threads d'arrière-plan (éventuellement en combinaison avec async / wait ). La mise à jour des mises à jour sur le thread d'interface utilisateur s'effectue généralement automatiquement lorsque la propriété mise à jour implémente INotifyPropertyChanged ou manuellement à l'aide du répartiteur du thread d'interface utilisateur.
Affectation de gestionnaires d'événements à un BackgroundWorker
Une fois que l'instance de BackgroundWorker a été déclarée, des propriétés et des gestionnaires d'événements doivent lui être attribués pour les tâches exécutées.
/* This is the backgroundworker's "DoWork" event handler. This
method is what will contain all the work you
wish to have your program perform without blocking the UI. */
bgWorker.DoWork += bgWorker_DoWork;
/*This is how the DoWork event method signature looks like:*/
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Work to be done here
// ...
// To get a reference to the current Backgroundworker:
BackgroundWorker worker = sender as BackgroundWorker;
// The reference to the BackgroundWorker is often used to report progress
worker.ReportProgress(...);
}
/*This is the method that will be run once the BackgroundWorker has completed its tasks */
bgWorker.RunWorkerCompleted += bgWorker_CompletedWork;
/*This is how the RunWorkerCompletedEvent event method signature looks like:*/
private void bgWorker_CompletedWork(object sender, RunWorkerCompletedEventArgs e)
{
// Things to be done after the backgroundworker has finished
}
/* When you wish to have something occur when a change in progress
occurs, (like the completion of a specific task) the "ProgressChanged"
event handler is used. Note that ProgressChanged events may be invoked
by calls to bgWorker.ReportProgress(...) only if bgWorker.WorkerReportsProgress
is set to true. */
bgWorker.ProgressChanged += bgWorker_ProgressChanged;
/*This is how the ProgressChanged event method signature looks like:*/
private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Things to be done when a progress change has been reported
/* The ProgressChangedEventArgs gives access to a percentage,
allowing for easy reporting of how far along a process is*/
int progress = e.ProgressPercentage;
}
Affectation de propriétés à un BackgroundWorker
Cela permet à BackgroundWorker d'être annulé entre les tâches
bgWorker.WorkerSupportsCancellation = true;
Cela permet au travailleur de signaler les progrès entre l'achèvement des tâches ...
bgWorker.WorkerReportsProgress = true;
//this must also be used in conjunction with the ProgressChanged event
Création d'une nouvelle instance BackgroundWorker
Un BackgroundWorker est généralement utilisé pour effectuer des tâches, parfois longues, sans bloquer le thread d'interface utilisateur.
// BackgroundWorker is part of the ComponentModel namespace.
using System.ComponentModel;
namespace BGWorkerExample
{
public partial class ExampleForm : Form
{
// the following creates an instance of the BackgroundWorker named "bgWorker"
BackgroundWorker bgWorker = new BackgroundWorker();
public ExampleForm() { ...
Utiliser un BackgroundWorker pour effectuer une tâche.
L'exemple suivant illustre l'utilisation d'un BackgroundWorker pour mettre à jour un WinForms ProgressBar. Le backgroundWorker mettra à jour la valeur de la barre de progression sans bloquer le thread d'interface utilisateur, affichant ainsi une interface utilisateur réactive pendant le travail en arrière-plan.
namespace BgWorkerExample
{
public partial class Form1 : Form
{
//a new instance of a backgroundWorker is created.
BackgroundWorker bgWorker = new BackgroundWorker();
public Form1()
{
InitializeComponent();
prgProgressBar.Step = 1;
//this assigns event handlers for the backgroundWorker
bgWorker.DoWork += bgWorker_DoWork;
bgWorker.RunWorkerCompleted += bgWorker_WorkComplete;
//tell the backgroundWorker to raise the "DoWork" event, thus starting it.
//Check to make sure the background worker is not already running.
if(!bgWorker.IsBusy)
bgWorker.RunWorkerAsync();
}
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
//this is the method that the backgroundworker will perform on in the background thread.
/* One thing to note! A try catch is not necessary as any exceptions will terminate the backgroundWorker and report
the error to the "RunWorkerCompleted" event */
CountToY();
}
private void bgWorker_WorkComplete(object sender, RunWorkerCompletedEventArgs e)
{
//e.Error will contain any exceptions caught by the backgroundWorker
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else
{
MessageBox.Show("Task Complete!");
prgProgressBar.Value = 0;
}
}
// example method to perform a "long" running task.
private void CountToY()
{
int x = 0;
int maxProgress = 100;
prgProgressBar.Maximum = maxProgress;
while (x < maxProgress)
{
System.Threading.Thread.Sleep(50);
Invoke(new Action(() => { prgProgressBar.PerformStep(); }));
x += 1;
}
}
}