193 votes

Comment utiliser le travailleur d'arrière-plan WPF

Dans mon application, je dois effectuer une série d'étapes d'initialisation, qui prennent 7 à 8 secondes, pendant lesquelles l'interface utilisateur ne répond plus. Pour résoudre ce problème, j'effectue l'initialisation dans un thread séparé :

public void Initialization()
{
    Thread initThread = new Thread(new ThreadStart(InitializationThread));
    initThread.Start();
}

public void InitializationThread()
{
    outputMessage("Initializing...");
    //DO INITIALIZATION
    outputMessage("Initialization Complete");
}

J'ai lu quelques articles sur le BackgroundWorker et comment il devrait me permettre de garder mon application réactive sans avoir à écrire un thread pour effectuer de longues tâches, mais je n'ai pas réussi à le mettre en œuvre. BackgroundWorker ?

0 votes

J'ai trouvé ce tutoriel utile, il comporte plusieurs exemples concis : elegantcode.com/2009/07/03/

0 votes

J'obtiens une erreur de confidentialité en cliquant sur ce lien.

351voto

Andrew Orsich Points 24503
  1. Ajouter en utilisant

    using System.ComponentModel;

  2. Déclarer Travailleur de fond :

    private readonly BackgroundWorker worker = new BackgroundWorker();

  3. S'abonner aux événements :

    worker.DoWork += worker_DoWork; worker.RunWorkerCompleted += worker_RunWorkerCompleted;

  4. Mettre en œuvre deux méthodes :

    private void worker_DoWork(object sender, DoWorkEventArgs e) { // run all background tasks here }

    private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //update ui once worker complete his work }

  5. Exécutez le travailleur de manière asynchrone chaque fois que vous en avez besoin.

    worker.RunWorkerAsync();

  6. Suivi des progrès (facultatif, mais souvent utile)

    a) s'abonner à ProgressChanged et utiliser ReportProgress(Int32) en DoWork

    b) fixer worker.WorkerReportsProgress = true; (crédits à @zagy)

0 votes

Existe-t-il un moyen d'accéder au DataContext dans ces méthodes ?

44voto

Owen Johnson Points 510

Vous pouvez également envisager d'utiliser Task au lieu des travailleurs de fond.

La façon la plus simple de le faire est dans votre exemple est Task.Run(InitializationThread); .

L'utilisation de tâches au lieu de travailleurs d'arrière-plan présente plusieurs avantages. Par exemple, les nouvelles fonctionnalités async/await de .net 4.5 utilisent Task pour l'enfilage. Voici de la documentation sur Task https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task

12 votes

Désolé de déterrer ce fil de discussion, mais .net 4.0 et 4.5 a ajouté des fonctionnalités intéressantes qui sont beaucoup plus faciles à utiliser que BackgroundWorker . J'espère pouvoir orienter les gens vers ce site.

2 votes

Maintenant que cette réponse est super vieille, regardez async y await . Ce sont des moyens intégrés au langage pour utiliser les tâches d'une manière beaucoup plus lisible.

5voto

bliss Points 197

En plus de ce qu'Andrew Orsich a dit, vous voudrez peut-être lire quelques exemples à ce sujet.

Voici un exemple de code utilisant un travailleur en arrière-plan et une barre de progression.

http://devtoolshed.com/content/c-download-file-progress-bar

et voici un petit tutoriel

http://www.dotnetperls.com/backgroundworker

et il y a un lien pour un autre exemple de progressbar+backgroundworker à la fin du tutoriel.

3voto

lko Points 1062

J'ai trouvé ceci ( WPF Multithreading : Utiliser le BackgroundWorker et signaler la progression à l'interface utilisateur. lien ) pour contenir le reste des détails qui manquent dans la réponse de @Andrew.

La seule chose que j'ai trouvée très utile, c'est que le fil de travail ne pouvait pas accéder aux contrôles de la fenêtre principale (dans sa propre méthode), mais que cela était possible en utilisant un délégué dans le gestionnaire d'événements de la fenêtre principale.

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    pd.Close();
    // Get a result from the asynchronous worker
    T t = (t)args.Result
    this.ExampleControl.Text = t.BlaBla;
};

1voto

Anuraj Points 6835

Essayez ce lien Classe BackgroundWorker dans MSDN qui contient un exemple d'utilisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X