WPF BackgroundWorker vs. Dispatcher

dans mon application WPF je dois faire une opération async puis je dois mettre à jour l'interface graphique. Et cette chose que je dois faire plusieurs fois à des moments différents avec des oparations différentes. Je connais deux façons de le faire: le répartiteur et le travailleur de fond.

parce que quand je le choisirai, il me sera difficile de revenir en arrière, je vous demande: qu'y a-t-il de mieux? Quelles sont les raisons du choix de l'un plutôt que l'autre?

Merci! Pileggi

30
demandé sur dmckee 2010-09-21 20:53:12

2 réponses

BackgroundWorker d'un autre côté exécute le code en même temps qu'il est invoqué, dans un thread séparé. Il a également est plus facile à utiliser que les threads true parce qu'il synchronise automatiquement (du moins je pense m'en souvenir correctement) avec le thread principal d'une application, celui responsable des contrôles et de la file d'attente de messages (le thread de Dispatcher dans le cas de WPF et Silverlight), donc il n'y a pas besoin d'utiliser le Dispatcher.Invoquer (ou contrôler.Invoke in WinForms) lors de la mise à jour des contrôles à partir du thread d'arrière-plan, bien que cela ne soit pas toujours recommandé.

comme L'a dit Reed, bibliothèque parallèle des tâches est une excellente alternative.

modifier: autres observations.

comme je l'ai dit ci-dessus, le répartiteur n'est pas vraiment multithread; il donne seulement l'illusion de lui, parce qu'il dirige des délégués que vous passez à lui à un autre moment. J'utiliserais le Dispatcher seulement quand le code ne traite vraiment que l'aspect de la vue d'une application - c'est-à-dire les contrôles, les pages, les fenêtres, et tout ça. Et bien sûr, son utilisation principale est en fait le déclenchement des actions de autres threads mettre à jour les contrôles correctement ou au bon moment (par exemple, définir la mise au point seulement après qu'un certain contrôle s'est rendu/s'est disposé complètement est plus facilement accompli en utilisant le répartiteur, parce que dans le rendu WPF n'est pas exactement déterministe).

BackgroundWorker peut rendre le code multithreaded beaucoup plus simple qu'il ne l'est normalement; c'est un concept simple à saisir, et surtout (si cela a du sens) vous pouvez en tirer des travailleurs personnalisés, qui peuvent être des classes spécialisées qui effectuent un tâche unique asynchrone, avec des propriétés qui peuvent fonctionner comme des paramètres, notification de progrès et d'annulation, etc. J'ai toujours trouvé BackgroundWorker une aide énorme (sauf quand j'ai dû en dériver pour garder la Culture du thread original pour maintenir la localisation correctement :P)

Le plus puissant, mais aussi un chemin plus difficile est d'utiliser le niveau le plus bas disponible, Système.Le filetage.Fil; cependant il est si facile de se tromper que ce n'est pas vraiment recommandé. Multithread la programmation est dur, c'est une donnée. Cependant, il y a beaucoup de bonnes informations dessus si vous voulez comprendre tous les aspects: cet excellent article par nos bons compagnons de Jon Skeet saute immédiatement à l'esprit (la dernière page de l'article a aussi un bon nombre de liens très intéressants).

dans .Net 4.0 nous avons une option différente, bibliothèque parallèle des tâches. Je n'ai pas encore beaucoup travaillé avec elle, mais de ce que j'ai vu c'est impressionnant (et PLINQ est tout simplement génial). Si vous avez la curiosité et les ressources pour l'apprendre, c'est ce que je recommande (il ne devrait pas prendre beaucoup à apprendre, après tout).

37
répondu Alex Paven 2010-09-21 20:55:45

BackgroundWorker est agréable si vous faites une seule opération, qui fournit des notifications de progrès et un événement d'achèvement. Toutefois, si vous allez exécuter la même opération plusieurs fois, ou en plusieurs opérations, alors vous aurez besoin de plus d'un BackgroundWorker. Dans ce cas, il peut devenir lourd.

si vous n'avez pas besoin des événements progress, alors utiliser le ThreadPool et le Dispatcher peut être plus simple - surtout si vous allez faire pas mal de choses différentes opérations.

si C# 4 est une option, cependant, l'utilisation de la bibliothèque parallèle des tâches est également une excellente option. Cela vous permet d'utiliser la configuration des tâches de continuation en utilisant le contexte de synchronisation actuel, qui fournit un modèle beaucoup plus simple et plus propre dans de nombreux cas. Pour plus de détails, voir mon billet de blog sur le sujet.

8
répondu Reed Copsey 2010-09-21 16:57:42