IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Fin d'un thread


Sujet :

C#

  1. #1
    Membre confirmé
    Inscrit en
    Mai 2009
    Messages
    172
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 172
    Par défaut Fin d'un thread
    Bonjour,

    J'ai développé aujourd'hui une partie de mon application avec les threads, j'ai déjà un peu de vécu avec les pthreads du c/c++ mais là c'est bien la première fois que je me lance dans le c# avec un problème bien concret.

    J'ai en gros 100 calculs à réaliser j'ai décidé de les diviser en 4 threads de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //Création des threads
                        thread1 = new Thread(new ParameterizedThreadStart(routineThreadMatch));
                        thread2 = new Thread(new ParameterizedThreadStart(routineThreadMatch));
                        thread3 = new Thread(new ParameterizedThreadStart(routineThreadMatch));
                        thread4 = new Thread(new ParameterizedThreadStart(routineThreadMatch));
                        thread1.IsBackground = true;
                        thread2.IsBackground = true;
                        thread3.IsBackground = true;
                        thread4.IsBackground = true;
                        while (m.Read())
                        {
     
     
    //Note pt est bien déclaré il s'agit d'une classe perso contenant 5 attributs je ne l'affiche pas pour alléger le code
                                ChoisirThread(pt);//La fonction va choisir un thread et lancer la simu
     
                                while (thread1.IsAlive && thread2.IsAlive && thread3.IsAlive && thread4.IsAlive) ; //On attend qu'un thread soit libre
     
     
                        } m.Dispose();
    Ma fonction ChoisirThread est une simple suite de condition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    if (!thread1.IsAlive)
                {
                    thread1.Start(pt);
                }
                else if (!thread2.IsAlive)
                {
                    thread2.Start(pt);
                }
                else if (!thread3.IsAlive)
                {
                    thread3.Start(pt);
                }
                else if (!thread4.IsAlive)
                {
                    thread4.Start(pt);
                }
    Enfin la "routine" de mon thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    try
                {
                    System.Data.SqlServerCe.SqlCeConnection connev = new System.Data.SqlServerCe.SqlCeConnection(connexion_bdd.ConnexionString);
     
                    connev.Open();
                    Simuler(pt.id);
                    connev.Close();
                    connev.Dispose();
                }
                catch (Exception pb)
                {
                    calculs.Erreur("Probleme routineThreadmatch"+ pb.Message);
                }
                try
                {
                    //On invoque le delegate pour la progressbar
                    Invoke((AugmenterProgressBar)Progres, 0);
     
                }
                catch (Exception ex) { return; }
                Thread.CurrentThread.Abort();//j'ai essayé avec ça à la fin de la fonction ça me semblait barbare mais ça ne change rien
    En fait mes 4 threads se lancent mais l'application bloque ensuite sur la boucle, avec des breakspoints j'ai bien vu que chaque thread arrivait bien à la fin de sa fonction pour invoquer le delegate de la progressBar (je ne sais pas si la progressBar a avancé, peut etre un problème de raffraichissement suite à cette boucle infinie).

    Je conçois bien que cette boucle n'est pas forcément très jolie jolie... Si vous avez une autre solution je suis preneur. Dans tous les cas la propriété isalive ne revient jamais à false, peut etre que j'ai mal du comprendre son utilité ?
    J'ai bien entendu parler de la fonction Join, mais je ne vois pas trop comment l'appliquer dans ce cas.

    Je débute avec la gestion de ces threads j'ai du omettre un simple détail, si vous pouviez m'aider...

    Merci d'avance,

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Tu n'as pas une exception qui se produit ? On ne peut pas redémarrer un thread terminé, ça cause une ThreadStateException. Il faut recréer un nouveau thread.

    Par contre, c'est très inefficace, car créer des threads, ça coute cher... Une meilleure approche serait de charger les données à traiter, les séparer en 4 lots, et donner un lot à chacun des threads.

    Mais de toutes façons, si ton traitement implique des appels à une base de données, ça n'a pas beaucoup d'intérêt de paralléliser... la parallélisation est surtout utile pour du calcul pur en mémoire, qui n'implique que le processeur. Dès que tu fais de l'IO (fichier, DB, réseau...), ça ne sert plus à grand chose de paralléliser.

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2009
    Messages
    172
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 172
    Par défaut
    Merci pour la réponse,

    On ne peut pas redémarrer un thread, cependant je n'ai pas l'impression qu'il en relance un, il bloque sur la boucle avec les isalive.

    Chaque thread insère les résultats de son calcul dans la base de données mais il y a quand meme une bonne partie de calcul avant donc je pensais qu'au final sur un grand jeu de données ça sera plus efficace.

  4. #4
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Bonjour.

    Réponse simple : autant utiliser directement le ThreadPool, soit directement, soit via Parallel. Le principe est que l'on enfile tous les calculs à réaliser et que le pool ajuste dynamiquement le nombre de threads à utiliser.

    Maintenant, sur le pourquoi ta solution actuelle est laide, d'abord un thread n'est pas fait pour être relancé, ensuite tu monopolises un cinquième thread (celui de départ) pour piloter les quatre autres. Une solution propre, similaire à ce que fait le ThreadPool, est d'avoir une file d'attente commune et que les quatre threads tournent en permanence, sans jamais s'arrêter, piochant dans la file le prochain travail à effectuer quand ils en ont terminé un. Enfin, quatre EventWaitHandle permettront de mettre en sommeil le thread principal jusqu'à ce que les ouvriers aient fini (quand un ouvrir n'a plus rien à piocher dans la file il appelle EventWaitHandle.Set, alors que le thread principal aura de son côté appelé Wait sur un tableau de quatre handles juste après avoir lancé les ouvriers).

    Enfin, tes threads ne se terminent jamais car ils ont en dernier appel Invoke qui lui-même attend le thread principal. Autrement dit ton principal attend que les ouvriers aient fini et réciproquement : blocage. Si tu tiens à mettre à jour l'UI depuis tes ouvriers il va te falloir un sixième thread ou commettre un bricolage sulfureux à base de BeginInvoke + Aplication.Run (les noms peuvent ne pas correspondre, tout dépend de la techno utilisée pour l'UI).

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Enfin, tes threads ne se terminent jamais car ils ont en dernier appel Invoke qui lui-même attend le thread principal. Autrement dit ton principal attend que les ouvriers aient fini et réciproquement : blocage.
    Bien vu, ça m'avait échappé

Discussions similaires

  1. Réponses: 3
    Dernier message: 13/11/2006, 14h28
  2. [thread]attendre la fin d'un thread?....
    Par babarpapa dans le forum Concurrence et multi-thread
    Réponses: 9
    Dernier message: 29/03/2006, 14h31
  3. [C#] Fin d'un Thread
    Par maitrebn dans le forum C#
    Réponses: 2
    Dernier message: 18/11/2005, 10h56
  4. [Thread] comment attendre la fin d'un thread?
    Par billynirvana dans le forum Concurrence et multi-thread
    Réponses: 11
    Dernier message: 24/08/2005, 10h43
  5. [MFC]Détection de la fin d'un thread
    Par Oberown dans le forum MFC
    Réponses: 17
    Dernier message: 25/08/2004, 11h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo