BackgroundWorker permet d’exécuter du code de manière synchrone sur un thread en tache de fond.
On créé donc un second thread pour exécuter du code afin de ne pas bloquer le thread principal.
Approche différente de async, qui ne créé pas de nouveau thread mais met en pause et en mémoire le code à exécuter de manière asynchrone et l'exécute par petit bout afin de ne pas bloquer le thread principal.
 |
The async-based approach to asynchronous programming is better than BackgroundWorker for IO-bound operations because the code is simpler and you don't have to guard against race conditions.
In combination with Task.Run, async programming is better than BackgroundWorker for CPU-bound operations because async programming separates the coordination details of running your code from the work that Task.Run transfers to the threadpool.
https://msdn.microsoft.com/en-us/library/mt674882.aspx |
BackgroundWorker et Dispatcher
Le Dispatcher permet de modifier des éléments (graphiques) du thread principal (MainThread) depuis un autre thread (background thread).
 |
Le Dispatcher n'est accessible que depuis la couche vue. |
|
var backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
backgroundWorker.RunWorkerAsync();
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// le Dispatcher permet de modifier des éléments graphiques
// depuis un thread autre que le thread graphique.
Dispatcher.Invoke(DispatcherPriority.Normal, new Action<TypeArgument1, TypeArgument2>(méthode, argument1, argument2);
bool b = (bool)System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Func<bool>(MaMethode));
mainWindow.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
mainWindow.LoadGantt(schedule);
}));
}
void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// si une Exception s'est produit durant le DoWork,
// alors elle sera stockée dans e.Error
if (e.Error != null)
{
MessageBox.Show(e.Error.Message, "Error", MessageBoxButton.OK,
MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.None);
}
else
{
}
}
|
 |
An object reference is required for the non-static field, method, or property.
Utiliser System.Windows.Application.Current.Dispatcher.Invoke |
Passer des arguments au BackgroundWorker
|
var backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += backgroundWorker_DoWork;
var monArgument = 10;
backgroundWorker.RunWorkerAsync(monArgument);
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// récupération de l'argument
int argument = (int)e.Argument;
}
backgroundWorker.DoWork += (obj, e) => WorkerDoWork(arg1, arg2);
void WorkerDoWork(string arg1, int arg2) { }
|
Callback
|
public delegate void Callback();
public void MaMethode()
{
if (this.Dispatcher.CheckAccess())
{ // modification des ressources de l'objet courant }
else
{ // relancer la méthode avec le bon thread
var myCallback = new Callback(MaMethode);
this.Dispatcher.Invoke(DispatcherPriority.Normal, myCallback);
}
}
|