Bonjour a tous,
Cela fait quelques semaines que je me suis décide a créer une petite application en WPF, et aujourd'hui c'est chose entamée !
Au fur et a mesure de mon développement, je me rends compte que le multithread m'est indispensable (que je n'ai pas beaucoup utilise non plus).
Le contexte général :
Mon programme est en fait un mini gestionnaire de téléchargements.
Ma conception :
Pour le multithread, j'utilise le ThreadPool de la classe du même nom afin de gérer la distribution de taches a mes threads. Je n'utilise que le minimum de thread possibles (2 pour un dual core donc) au départ mais je suis censé l'augmenter comme bon me semble.
Je lance donc une queue de 400 taches que mon ThreadPool exécute 2 par 2.
Chaque thread = 1 téléchargement d'un fichier sachant qu'un fichier peut contenir plusieurs liens a télécharger.
J'ai mon formulaire MainWindow, qui contient un StackPanel vide au départ.
Une fois que j'appuies sur un bouton, les 400 taches se mettent en attente et les 2 téléchargements s'effectuent. (Via la classe WebClient)
Le StackPanel est cense contenir un UserControl (que je vais appeler ToxiBar) qui contient quelques labels, boutons et une progressBar.
Vous l'aurez surement compris, ce StackPanel est censé afficher l'état d'avancement du téléchargement en cours et que donc, il devrait y avoir 2 ToxiBars a chaque fois..
Mon probleme :
La tache, que j'envoisa mon ThreadPool, est la méthode d'un nouvel Objet. Cette objet est donc sur un thread a part, en dehors de celui de mon MainWindow.
Comme vous le savez, il n'est pas possible (de manière propre) de modifier le formulaire via un autre Thread que celui qui l'a créé.
Ce que je voudrais donc faire, c'est qu'a chaque fois qu'un nouveau Thread est lance, un nouveau composant ToxiBar s'ajoute a mon StackPanel, et qu'il affiche la progression du téléchargement de ce Thread.
Mes questions :
- Vu que j'utilise le ThreadPool, je n'ai aucun controle sur ces threads, comment un thread peut envoyer au thread principal son id ?
- Voyez-vous une meilleure manière/conception ?!
Mes reflexions :
- Je voulais créer une Hashtable dans mon MainWindow, y ajouter comme cle, l'id unique de mon thread, et comme valeur, l'objet ToxiBar qui lui est associe.. Cependant, via mon thread je ne peux accéder aux membres de mon MainWindow, sauf si je le déclare en static mais je trouve ca moche..
D'autant plus l'accès a la Hastable n'est pas thread-safe, si on ne la synchronise pas (fonction Synchronized me semble d'après le MSDN).
- Une methode static sur mon formulaire ? Mais elle n'aura pas accès aux membres non static comme ma hashtable, et encore une fois je trouve que ca fait moche si je la rends static non ?
Pour les controles par contre je suppose que ca se fait par les Invoke, je l'ai déjà fait ce ne pose pas de problème.
- J'ai aussi songe a l'utilisation de la classe ManagedThreadPool de l'ami Stephen Toub de chez Microsoft disponible ici : http://www.koders.com/csharp/fidD26A...3Asemaphore.cs
Elle m'a l'air intéressante et avec celle-ci j'aurai des infos sur tous mes threads depuis mon formulaire et pourrai donc associer un thread a un ToxiBar..
Mais selon Ericv (de Microsoft aussi) un Thread est très couteux, et qu'il fallait privilégier les Tasks (voir son article : partie 1 et partie 2
Or, cette classe n'utilise que les Threads..
Me conseillez-vous d'utiliser cette classe, mais en remplaçant les Threads par des Tasks ?
Ayant 400 taches a donner, et les exécutant 2 par 2 (sachant que je peux augmenter ce nombre comme bon me semble ce n'est pas une valeur en dur, fixe, mais bien dynamique).. ce la peut se mettre a consommer un peu trop de mémoire CPU..
Voili voila.. Je crois avoir tout dit.. J'ai écris ce message en plusieurs fois donc s'il manque des précisions, n'hésitez pas je vous répondrai
Merci !
Partager