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 :

Lancer une Thread après la fin de deux autres [Débutant]


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 53
    Points : 29
    Points
    29
    Par défaut Lancer une Thread après la fin de deux autres
    Bonjours,

    Un bout de code vaut mieux qu'une grande explication

    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
    private void Generation()
    {
    btnLancer.Enabled = false;
     
    Workbook Wb1 = new Workbook(@txtbox1.Text);
    Workbook Wb2 = new Workbook(@txtbox2.Text);
     
    //Lecture Fichier 1 (Thread1)
    Thread T_CollectionFichier1 = new Thread(=new ParameterizedThreadStart(CollectionFichier1));
    T_CollectionFichier1.Start(Wb1)
     
    //Lecture Fichier 2 (Thread2)
    Thread T_CollectionFichier2 = new Thread(=new ParameterizedThreadStart(CollectionFichier2));
    T_CollectionFichier1.Start(Wb2)
     
    //Generation du FichierG (Thread 3)
    Thread T_GenXLS = new Thread(new ThreadStart(GenXLS));
    T_GenXLS.Start();
     
    btnLancer.Enabled = true;
    }
    Je m'explique maintenant :

    Le but est d'éxecuter mon thread3 apres que le thread1 et 2 sois terminé. J'ai déja fait des test avec le join en faisant :

    mais il dit qu'il ne c'est pas éxécuter (normal vu que les deux permiers Thread son très long).

    Merci d'avance !

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    Utilisez cette méthode pour vous assurer qu'un thread s'est arrêté. L'appelant sera indéfiniment bloqué si le thread ne s'arrête pas. Si le thread est déjà arrêté lorsque Join est appelé, le retour de la méthode est immédiat.

    Cette méthode change l'état du thread appelant de manière à inclure ThreadState.WaitSleepJoin. Vous ne pouvez pas appeler Join sur un thread dont l'état est ThreadState.Unstarted.
    Donc je vois pas d'ou peut venir le problème

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //Main Thread attend que le Thread1 et 2 soit terminer
    T_CollectionFichier1.Join();
    T_CollectionFichier2.Join();
    //Lancement du Thread3
    Thread T_GenXLS = new Thread(new ThreadStart(GenXLS));
    T_GenXLS.Start();
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 53
    Points : 29
    Points
    29
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //Main Thread attend que le Thread1 et 2 soit terminer
    T_CollectionFichier1.Join();
    T_CollectionFichier2.Join();
    //Lancement du Thread3
    Thread T_GenXLS = new Thread(new ThreadStart(GenXLS));
    T_GenXLS.Start();
    Merci ! Moi j'avait pas fait comme ça ! J'était partit sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //Main Thread attend que le Thread1 et 2 soit terminer
    T_CollectionFichier1
    T_CollectionFichier2
    //Lancement du Thread3
    Thread T_GenXLS = new Thread(new ThreadStart(GenXLS));
    T_GenXKS.Join();
    T_GenXLS.Start();
    En pensant que l'appelant était l'objet qui utiliser la méthode .join().


    Je test ça tout de suite.

  4. #4
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Autre possibilité, utiliser directement les objets de synchro. Cela te permet éventuellement de démarrer le troisième, une fois que les deux premiers ont terminées les tâches utiles, sans pour autant avoir terminé le thread.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 53
    Points : 29
    Points
    29
    Par défaut
    Bon alors résultat : ça marche j'ai bien ce que je voulait, le problème c'est que ça bloque complétement ma form et mon invoke sur ma progress bar.

    Est ce qu'il y aurait un moyen de démarrer la troisième thread avec un .IsAlive et un while ? J'ai l'idée mais pas la conception.


    @BlueDeep

    une fois que les deux premiers ont terminées les tâches utiles
    Mes deux thread font qu'une tache utile Mais si la synchro peut permettre a ma troisième thread de démarrer après les deux autre ça serait parfait.

  6. #6
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par Zarrows Voir le message
    Mes deux thread font qu'une tache utile Mais si la synchro peut permettre a ma troisième thread de démarrer après les deux autre ça serait parfait.
    Exemple (torché en 2mn, donc pas à prendre au pied de lettre, il est là juste pour te montre le principe du mécanisme) :

    Ici, les deux premiers thread démarrent, le thread lanceur (le main ici) attend que les deux autres thread aient confirmé qu'il peut lancer le troisième, et continuent.

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    public class ThreadTest
    {
    	ManualResetEvent _event1;
    	ManualResetEvent _event2;
    	public ThreadTest(ManualResetEvent event1, ManualResetEvent event2)
    	{
    		_event1 = event1;
    		_event2 = event2;
    	}
    	private void longLoop()
    	{
    		for (int i = 0; i < 200; i++)
    		{
    			Thread.Sleep(10);
    		}
    	}
    	public void LongMethod1()
    	{
    		Console.WriteLine("LongMethod1 démarre");
    		longLoop();
    		_event1.Set(); // Thread sur LongMethod3 autorisé à démarré
    		Console.WriteLine("LongMethod1 autorise LongMethod3 à démarrer");
    		longLoop();
    		Console.WriteLine("LongMethod1 termine");
    	}
     
    	public void LongMethod2()
    	{
    		Console.WriteLine("LongMethod2 démarre");
    		longLoop();
    		_event2.Set(); // Thread sur LongMethod3 autorisé à démarré
    		Console.WriteLine("LongMethod2 autorise LongMethod3 à démarrer");
    		longLoop();
    		Console.WriteLine("LongMethod2 termine");
    	}
    	public void LongMethod3()
    	{
    		Console.WriteLine("LongMethod3 démarre");
    		longLoop();
    		Console.WriteLine("LongMethod3 termine");
    	}
     
    }
    class Program
    {
    	static void Main(string[] args)
    	{
    		ManualResetEvent event1 = new ManualResetEvent(false);
    		ManualResetEvent event2 = new ManualResetEvent(false);
     
    		ThreadTest threadTest = new ThreadTest(event1, event2);			
    		Thread thread1 = new Thread(new ThreadStart(threadTest.LongMethod1));
    		Thread thread2 = new Thread(new ThreadStart(threadTest.LongMethod2));
    		thread1.Start();
    		thread2.Start();
    		ManualResetEvent.WaitAll(new ManualResetEvent[] { event1, event2 });
    		Thread thread3 = new Thread(new ThreadStart(threadTest.LongMethod3));
    		thread3.Start();
    		Console.ReadKey();
    	}
    }

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 53
    Points : 29
    Points
    29
    Par défaut
    Et cela ne va pas bloquer ma main thread ?

  8. #8
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par Zarrows Voir le message
    Et cela ne va pas bloquer ma main thread ?
    Ici, j'ai choisi que la main attendent que les deux seconaires se signalent.

    Si je ne veux pas bloquer la "main", je peux mettre le mécanisme d'attente dans un autre thread qui se contente d'être l'ordonnanceur des trois autres.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  9. #9
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Exemple modifé pour illuster ce que je te dis (ici, donc 5 threads : 1 main, 1 scheduler, et les 3 autres) , le main continuant à bosser (ici un écho clavier, suffisant pour la démo).

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    public class ThreadTest
    {
    	ManualResetEvent _event1;
    	ManualResetEvent _event2;
    	public ThreadTest(ManualResetEvent event1, ManualResetEvent event2)
    	{
    		_event1 = event1;
    		_event2 = event2;
    	}
    	private void longLoop()
    	{
    		for (int i = 0; i < 1000; i++)
    		{
    			Thread.Sleep(10);
    		}
    	}
    	public void LongMethod1()
    	{
    		Console.WriteLine("LongMethod1 démarre");
    		longLoop();
    		_event1.Set(); // Thread sur LongMethod3 autorisé à démarré
    		Console.WriteLine("LongMethod1 autorise LongMethod3 à démarrer");
    		longLoop();
    		Console.WriteLine("LongMethod1 termine");
    	}
     
    	public void LongMethod2()
    	{
    		Console.WriteLine("LongMethod2 démarre");
    		longLoop();
    		_event2.Set(); // Thread sur LongMethod3 autorisé à démarré
    		Console.WriteLine("LongMethod2 autorise LongMethod3 à démarrer");
    		longLoop();
    		Console.WriteLine("LongMethod2 termine");
    	}
    	public void LongMethod3()
    	{
    		Console.WriteLine("LongMethod3 démarre");
    		longLoop();
    		Console.WriteLine("LongMethod3 termine");
    	}
     
    }
    class Program
    {
    	private static void scheduler()
    	{
    		ManualResetEvent event1 = new ManualResetEvent(false);
    		ManualResetEvent event2 = new ManualResetEvent(false);
     
    		ThreadTest threadTest = new ThreadTest(event1, event2);
    		Thread thread1 = new Thread(new ThreadStart(threadTest.LongMethod1));
    		Thread thread2 = new Thread(new ThreadStart(threadTest.LongMethod2));
    		thread1.Start();
    		thread2.Start();
    		ManualResetEvent.WaitAll(new ManualResetEvent[] { event1, event2 });
    		Thread thread3 = new Thread(new ThreadStart(threadTest.LongMethod3));
    		thread3.Start();
     
    	}
    	static void Main(string[] args)
    	{
    		Thread thread_scheduler = new Thread(new ThreadStart(scheduler));
    		thread_scheduler.Start();
    		while (true)
    		{
    			Console.WriteLine("Entrer une caractére, F pour finir");
    			ConsoleKeyInfo keyInfo = Console.ReadKey();
    			if (keyInfo.KeyChar == 'F')
    			{
    				Environment.Exit(0);
    			}
    			else
    			{
    				Console.WriteLine(keyInfo.KeyChar);
    			}
    		}
    	}
    }

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 53
    Points : 29
    Points
    29
    Par défaut
    Pourquoi tu as mit les 3 Thread dans une autre classe ?

  11. #11
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par Zarrows Voir le message
    Pourquoi tu as mit les 3 Thread dans une autre classe ?
    Il s'agit d'un EXEMPLE.

    Donc on essaye de faire DIDACTIQUE et LISIBLE.

    Et que ça correspond à ce qui se fera en pratique (ma classe "métier" n'a pas à contenir son propre code de scheduling).

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  12. #12
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Une dernière version plus compacte avec les threads se lançant tous sur la même méthode et passage de paramètres.
    Maintenant tu as tous les éléments pour continuer.

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    struct MyThreadsParam
    {
    	public ManualResetEvent SyncEvent;
    	public int ThreadNumber;
    }
    public class ThreadTest
    {
    	private static void longLoop()
    	{
    		for (int i = 0; i < 1000; i++)
    		{
    			Thread.Sleep(10);
    		}
    	}
    	public void LongMethod(object myParam)
    	{
    		MyThreadsParam param = (MyThreadsParam)myParam;
    		Console.WriteLine("LongMethod{0} démarre", param.ThreadNumber);
    		longLoop();
    		if (param.SyncEvent != null)
    		{
    			param.SyncEvent.Set(); // Thread sur LongMethod3 autorisé à démarré
    			Console.WriteLine("LongMethod{0} autorise LongMethod3 à démarrer", param.ThreadNumber);
    		}
    		longLoop();
    		Console.WriteLine("LongMethod{0} termine", param.ThreadNumber);
    	}
    }
    class Program
    {
    	static ThreadTest threadTest = new ThreadTest();
     
    	private static MyThreadsParam scheduleOneThread(int number, bool hasSyncEvent)
    	{
    		ManualResetEvent sync_event = null;
    		if (hasSyncEvent)
    		{
    			sync_event = new ManualResetEvent(false);
    		}
    		MyThreadsParam threadParam = new MyThreadsParam() { SyncEvent = sync_event, ThreadNumber = number };
    		Thread thread = new Thread(new ParameterizedThreadStart(threadTest.LongMethod));
    		thread.Start(threadParam);
    		return threadParam;
     
    	}
    	private static void scheduler()
    	{
    		MyThreadsParam threadParam1 = scheduleOneThread(1, true); // on démarre 1
    		MyThreadsParam threadParam2 = scheduleOneThread(2, true); // on démarre 2
    		ManualResetEvent.WaitAll(new ManualResetEvent[] { threadParam1.SyncEvent, threadParam2.SyncEvent });
    		MyThreadsParam threadParam3 = scheduleOneThread(3, false); // on démarre 3, quand 1 et 2 ont signalé
    	}
    	static void Main(string[] args)
    	{
    		Thread thread_scheduler = new Thread(new ThreadStart(scheduler));
    		thread_scheduler.Start();
    		while (true)
    		{
    			Console.WriteLine();
    			Console.WriteLine("Entrer une caractére, F pour finir : ");
    			ConsoleKeyInfo keyInfo = Console.ReadKey();
    			if (keyInfo.KeyChar == 'F')
    			{
    				Environment.Exit(0);
    			}
    		}
    	}
    }

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 53
    Points : 29
    Points
    29
    Par défaut
    Après de longues heure de travail voici ce que j'ai fait :

    J'ai creer une thread qui est lancer à partir de mon main, Cet thread est interrompu après le lancement des deux premières pour attendre de lancer la troisième.

    Merci BlueDeep de m'avoir aidé. Je n'est pas bien compris l'histoire de ManualResetEvent et la solution que j'ai trouvé me parait plus simple pour un débutant comme moi. Merci encore !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lancer un storyboard aprés la fin d'un autre
    Par theneoboy dans le forum Windows Presentation Foundation
    Réponses: 7
    Dernier message: 27/05/2010, 17h36
  2. Comment lancer une procédure après affichage d'une form
    Par Fouinard dans le forum Macros et VBA Excel
    Réponses: 14
    Dernier message: 29/10/2008, 09h52
  3. [exel-vba] lancer une Function apres la creation de la feuille
    Par lio62 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 06/02/2008, 10h55
  4. lancer une page html à la fin de ma vidéo mp4
    Par supermac dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 16/11/2007, 10h35
  5. Réponses: 4
    Dernier message: 10/03/2006, 17h25

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