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

Windows Forms Discussion :

[MT] Thread et Winforms


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    r0d
    r0d est actuellement connecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 299
    Billets dans le blog
    2
    Par défaut [MT] Thread et Winforms
    Bonjour tout le monde,

    j'ai besoin de faire une fenêtre (winform) dans laquelle:
    1/ un contrôle est modifié par un thread.
    2/ ma fenêtre (celle qui contient le contrôle) doit être accessible par l'utilisateur en même temps que le thread modifie un de ses contrôle.

    Alors, pour tenter d'y voir plus clair, je me suis inspiré de ce tuto, et en particulier ce chapitre.

    Je suis arrivé à un problème trés simple et trés concret:
    Une form (form1) avec un bouton "start" et une ProgressBar. Quand je clique sur "start", j'ai un Thread qui se lance et qui incrémente progressivement la ProgressBar. J'ai fait une classe qui s'occupe du thread et qui ressemble à ça:
    Code C# : 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
    class ProgressThread
    {
        private ProgressBar _pbar;
        private Form _mainWin;
        private delegate void InvokeMethod();
     
        public ProgressThread(Form mainWin, ProgressBar pbar)
        {
            _pbar = pbar;
            _mainWin = mainWin;
     
            _pbar.Minimum = 0;
            _pbar.Maximum = 100;
            _pbar.Step = 1;
        }
     
        public void Start()
        {
            Thread theThread = new Thread(new ThreadStart(TheThread));
            theThread.Start();
        }
     
        private void TheThread()
        {
            _mainWin.BeginInvoke(new InvokeMethod(UpdatePBar));
        }
     
        private void UpdatePBar()
        {
            while (_pbar.Value < 100)
            {
                _pbar.PerformStep();
                Thread.Sleep(50);
            }
        }
    }
    Jusqu'ici tout va bien sauf que, dès que mon thread est lancé, et jusqu'à ce qu'il soit achevé, je n'ai plus la main sur ma form1 (je voudrais, notamment, la déplacer).

    ¿Auriez-vous une idée?

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Par défaut
    Bonsoir r0d,

    en fait c'est le comportement normal que tu as codé. =)

    En fait, quand tu lances ton thread nommé (new Thread blabla), la procedure de lancement va juste invoker (non bloquant) la methode UpdatePBar sur le thread du control et se terminer, donc le thread du control va se retrouver dans une boucle lui demandant d'incrementer la progressBar puis de 'sleeper' 50 ms et ce 100 fois. La consequence de ceci est que ta form ne repond plus puisqu'elle execute la methode ci dessus.

    Quand tu veux invoker du code sur le thread du controle, il faut que ce soit le plus tard ainsi que le plus court possible. De meme, il ne faut jamais (enfin AMHA) invoker une methode potentiellement longue et bloquante (ce qui est le cas ici). Je te propose (sur base de ton code) cette solution :

    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
     
        class ProgressControl
        {
            private ProgressBar _pbar;
            private Form _mainWin;
     
            public ProgressControl(Form mainWin, ProgressBar pbar)
            {
                _pbar = pbar;
                _mainWin = mainWin;
     
                _pbar.Minimum = 0;
                _pbar.Maximum = 100;
                _pbar.Step = 1;
            }
     
            public void Start()
            {
                Thread theThread = new Thread(new ThreadStart(UpdatePBar));
                theThread.Start();
            }
     
            private void UpdatePBar()
            {
                while (_pbar.Value < 100)
                {
                    _mainWin.Invoke(new MethodInvoker(
                        delegate
                        {
                            _pbar.PerformStep();
                        }));
                    Thread.Sleep(50);
                }
            }
        }
    Dans ce cas, on invoke uniquement le PerformStep dans le thread du control, le sleep sleepera (sic) le thread nommé que tu as lancé, et ton thread d'UI restera reactif. Juste une note au passage, je vois que tu as declaré un type delegué sur une signature void (void), cela existe deja en standard, c'est MethodInvoker dans le NS System.Windows.Forms.

    Bon courage. =)

  3. #3
    r0d
    r0d est actuellement connecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 299
    Billets dans le blog
    2
    Par défaut
    Impeccable

    Je viens du c++, et visiblement, les threads fonctionnent différemment en c++ et en c#

    Encore merci

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

Discussions similaires

  1. Thread et Winform
    Par r0d dans le forum C#
    Réponses: 2
    Dernier message: 01/07/2011, 13h46
  2. thread et winform(débutant)
    Par eldrad95 dans le forum Windows Forms
    Réponses: 10
    Dernier message: 08/01/2010, 15h42
  3. Thread in Winform
    Par totom1982 dans le forum VC++ .NET
    Réponses: 2
    Dernier message: 21/03/2007, 20h00
  4. Réponses: 2
    Dernier message: 18/07/2006, 12h20
  5. [VB.NET][WINFORMS] Multi threading
    Par joKED dans le forum Windows Forms
    Réponses: 2
    Dernier message: 28/02/2006, 11h48

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