none
Problème lié au while(true). RRS feed

  • Question

  • Voilà mon problème: 

    J'ai voulut avoir une action qui se répète indéfiniment donc j'ai utilisé while(true). Le problème, c'est que lorsque que la boucle while(true) est enclenchée, rien ne fonctionne à coté. Par exemple j'ai une boucle de 3sec grace à un timer, cependant lorsqu'il y a la boucle while(true), le timer ne marche plus et l'application semble ne plus fonctionner même si les fonction qui sont dans la boucle continuent toujours.

    Voilà un petit morceau de mon code :

     
    //la boucle   
    
       private void button1_Click(object sender, EventArgs e)
            {
                timer1.Start();
                while(true) 
                {
               //code qui se répète le plus rapidement possible.  
                }
            }
    
    
    //timer
    
        private void timer1_Tick(object sender, EventArgs e)
            {
            //code qui se répète chaque 3 secondes.
            }
    

    mercredi 18 juillet 2018 11:55

Réponses

  • Bonjour,

    Apriori vous faîtes du WinForm, et le code que vous avez écrit est une très mauvaise idée.

    En effet WinForm est un système évènementiel, l'application reçoit tout un tas d'événements (souris déplacée, bouton de souris appuyé, relaché, touche clavier appuyée, relachée, etc...), et une application WinForm traite chacun de ces événements dans une boucle infinie (sauf quand le message "Quitter l'application" arrive) que l'on appelle "Pompe à messages" pour transformer ces événements (messages Windows) en événements .NET sur les contrôles de votre formulaire.

    Dans votre cas, lorsqu'on clique sur votre bouton, vous provoquez une boucle infinie: résultat vous ne sortez jamais de votre boucle et la pompe à message n'est plus exécutée, donc tout ce que vous demandez à votre application est en attente d'être traité. Windows le détecte normalement, et vous indique dans la barre de titre "(Ne répond pas)".

    Votre timer provoque un événement toutes les 3 secondes, mais c'est un message Windows traité par la pompe à message, donc comme vous l'empêchez de s'exécuter votre timer n'est pas traité.

    Vous avez deux possibilités:

    1) Forcer la pompe à message à s'exécuter dans votre boucle infinie en appelant très régulièrement la méthode

    Application.DoEvents();
    Tous les événements en attente seront traités dans la pompe à message, votre application va "répondre" mais de manière "saccadée". Mais votre timer s'exécutera, en revanche vous n'aurez pas une grande précision de 3 secondes se sera plus et très variable.

    2) Exécuter votre code dans un BackgroundWorker ou un thread, mais là votre code va être un peu plus compliqué, notamment si vous devez manipuler l'interface utilisateur (votre formulaire), aussi je vous conseille de lire des articles comme:

    - https://docs.microsoft.com/fr-fr/dotnet/framework/winforms/controls/backgroundworker-component-overview

    - http://a-sidahmed.blogspot.com/2013/04/background-worker-et-progression.html

    - https://www.developpez.net/forums/d675711/dotnet/developpement-windows/windows-forms/executer-traitement-thread-backgroundworker/

    Cordialement,


    Yan Grenier

    Merci de bien vouloir "Marquer comme réponse", les réponses qui ont répondues à votre question, et de noter les réponses que vous avez trouvé utiles.

    • Marqué comme réponse Lukas_V mercredi 18 juillet 2018 14:23
    mercredi 18 juillet 2018 13:21

Toutes les réponses

  • Bonjour,

    Apriori vous faîtes du WinForm, et le code que vous avez écrit est une très mauvaise idée.

    En effet WinForm est un système évènementiel, l'application reçoit tout un tas d'événements (souris déplacée, bouton de souris appuyé, relaché, touche clavier appuyée, relachée, etc...), et une application WinForm traite chacun de ces événements dans une boucle infinie (sauf quand le message "Quitter l'application" arrive) que l'on appelle "Pompe à messages" pour transformer ces événements (messages Windows) en événements .NET sur les contrôles de votre formulaire.

    Dans votre cas, lorsqu'on clique sur votre bouton, vous provoquez une boucle infinie: résultat vous ne sortez jamais de votre boucle et la pompe à message n'est plus exécutée, donc tout ce que vous demandez à votre application est en attente d'être traité. Windows le détecte normalement, et vous indique dans la barre de titre "(Ne répond pas)".

    Votre timer provoque un événement toutes les 3 secondes, mais c'est un message Windows traité par la pompe à message, donc comme vous l'empêchez de s'exécuter votre timer n'est pas traité.

    Vous avez deux possibilités:

    1) Forcer la pompe à message à s'exécuter dans votre boucle infinie en appelant très régulièrement la méthode

    Application.DoEvents();
    Tous les événements en attente seront traités dans la pompe à message, votre application va "répondre" mais de manière "saccadée". Mais votre timer s'exécutera, en revanche vous n'aurez pas une grande précision de 3 secondes se sera plus et très variable.

    2) Exécuter votre code dans un BackgroundWorker ou un thread, mais là votre code va être un peu plus compliqué, notamment si vous devez manipuler l'interface utilisateur (votre formulaire), aussi je vous conseille de lire des articles comme:

    - https://docs.microsoft.com/fr-fr/dotnet/framework/winforms/controls/backgroundworker-component-overview

    - http://a-sidahmed.blogspot.com/2013/04/background-worker-et-progression.html

    - https://www.developpez.net/forums/d675711/dotnet/developpement-windows/windows-forms/executer-traitement-thread-backgroundworker/

    Cordialement,


    Yan Grenier

    Merci de bien vouloir "Marquer comme réponse", les réponses qui ont répondues à votre question, et de noter les réponses que vous avez trouvé utiles.

    • Marqué comme réponse Lukas_V mercredi 18 juillet 2018 14:23
    mercredi 18 juillet 2018 13:21
  • Merci beaucoup de votre réponse! Tout cela est bien plus clair! J'ai enfin compris le but des 'threads' !

    Merci - Lukas V

    mercredi 18 juillet 2018 13:53