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 :

Utilisation d'une Progressbar


Sujet :

Windows Forms

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mai 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2008
    Messages : 8
    Points : 11
    Points
    11
    Par défaut Utilisation d'une Progressbar
    Bonjour

    Débutant en C# on m'a demander de réaliser une application permettant de mettre a jour un logiciel.

    Et pour commencer on m'a demander de regarder le fonctionnement d'une progressbar, j'ai donc réaliser une application simple déclenchant un progresse bar sur le clic d'un bouton, et stoppant la progression sur le clic d'un autre bouton

    Cependant cette petit application, pourtant très simple ne fonctionne pas :s

    Pouvez vous m'aidez ?

    Le message d'erreur est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Opération inter-threads non valide : le contrôle 'progressBar1' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé.

    Je joins mon code

    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
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
     
    namespace LALALA
    {
        public partial class Form1 : Form
        {
            public Thread T1;
            public bool test = false;
            public bool Resultat = false;
     
              public Form1()
            {
                InitializeComponent();
                T1 = new Thread(new ThreadStart(InitProgressBar));
     
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
     
                T1.Start();
            }
     
            private void button3_Click(object sender, EventArgs e)
            {
                test = true;
            }
     
     
                    private void InitProgressBar()
            {            
                while (test == false)
                {
                    //Fonction qui incrémente la valeure de la progressbar
                    progressBar1.Value = progressBar1.Value % progressBar1.Maximum + 1;
                    Thread.Sleep(50);
                    progressBar1.Update();
                }
     
            }
        }
    }
    Merci d'avance

    Rogue 9

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Réunion

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 277
    Points : 1 521
    Points
    1 521
    Par défaut
    Regarde du côté de la classe BackgroundWorker plutôt que d'utiliser un thread.

  3. #3
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mai 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2008
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    Hum je m'en vais voir ça, merci pour l'info

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 27
    Points : 33
    Points
    33
    Par défaut
    Le problème est un cas classique de cross thread.
    Tu lances un thread qui va s'occuper de changer les propriétés d'un composant visuel (en l'occurrence ici ta progressBar). Pour modifier les propriétés d'un composant visuel, il faut forcément le faire dans le thread de la GUI .
    Tu peux le faire grâce à la méthode Invoke ou BeginInvoke (Invoke appel le thread de la GUI de manière synchrone, et BeginInvoke le fait de manière asynchrone)

    essaie le code suivant :
    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
    using System;
    using System.Threading;
    using System.Windows.Forms;
     
    namespace WindowsApplication3
    {
        public partial class Form1 : Form
        {
            public bool Resultat = false;
            public Thread T1;
            public bool test = false;
     
            public Form1()
            {
                InitializeComponent();
                T1 = new Thread(InitProgressBar);
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
                T1.Start();
            }
     
            private void button3_Click(object sender, EventArgs e)
            {
                test = true;
            }
     
            private void InitProgressBar()
            {
                while (test == false)
                {
                    IncreaseProgressBarValue();
                    Thread.Sleep(50);
                }
            }
     
            private void IncreaseProgressBarValue()
            {
                if (InvokeRequired) Invoke(new IncreaseProgressBarValueDelegate(IncreaseProgressBarValue));
                else
                {
                    progressBar1.Value = progressBar1.Value%progressBar1.Maximum + 1;
                }
            }
     
            #region Nested type: IncreaseProgressBarValueDelegate
     
            private delegate void IncreaseProgressBarValueDelegate();
     
            #endregion
        }
    }

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 27
    Points : 33
    Points
    33
    Par défaut
    J'ai oublié une petite précision : la propriété InvokeRequired t'indique si la méthode dans laquelle tu te trouves a été appelée par un autre thread que celui de la GUI......

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 27
    Points : 33
    Points
    33
    Par défaut
    Je te poste une autre solution qui s'apparente à la précédente . Tu accéder aux propriétés de ta progressbar, tu peux passer par le synchronizationContext. Il possède deux méthodes intéressantes comme Send et Post (Send est synchrone, Post est assynchrone) qui te permettent aussi d'exécuter la méthode passée sur le thread de la GUI :


    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
    using System;
    using System.Threading;
    using System.Windows.Forms;
     
    namespace WindowsApplication3
    {
        public partial class Form1 : Form
        {
            public bool Resultat = false;
            public Thread T1;
            public bool test = false;
            private SynchronizationContext context ;
     
            public Form1()
            {
                InitializeComponent();
                context = WindowsFormsSynchronizationContext.Current;
                T1 = new Thread(InitProgressBar);
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
                T1.Start();
            }
     
            private void button3_Click(object sender, EventArgs e)
            {
                test = true;
            }
     
            private void InitProgressBar()
            {
                while (test == false)
                {
                    context.Send(IncreaseProgressBarValue,null);
                    Thread.Sleep(50);
                }
            }
     
            private void IncreaseProgressBarValue(object value)
            {
                    progressBar1.Value = progressBar1.Value%progressBar1.Maximum + 1;
            }
        }
    }

  7. #7
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mai 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2008
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    waou, merci pour vos deux réponses aussi complète qu'instructive, et qui répondent parfaitement a ma demande, me reste plus qu'a comprendre le sens de la démarche et la logique du C# ( assez proche semble-t'il du java mais avec l'assistant VS en plus )

    merci bien

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Points : 627
    Points
    627
    Par défaut
    Salut,

    la logique est somme toute plutot simple à comprendre, c'est l'application qui l'est moins (deleguation etc) : Quand tu créés une form (et plus generalement tout ce qui herite de control), ce dernier est "bindé" au thread qui l'a créé (c'est du à l'architecture des UI sous windows), de fait, il est dangeureux de modifier un control sur un thread autre que celui qui l'a créé, et en general, il te jete une exception si tu le fais.

    Le principe du pattern invoke, est de passer au thread de la form, une methode à executer; ainsi les methodes d'ui (ici touchant une progressbar) seront tout le temps executé par le thread qui a créé ces derniers.

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

Discussions similaires

  1. Utilisation d'une progressBar
    Par Jean-Luc80 dans le forum VB.NET
    Réponses: 16
    Dernier message: 22/12/2013, 08h11
  2. [VB6] Utiliser une Progressbar (barre de progression)
    Par Sytchev3 dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 29/03/2006, 14h57
  3. Utilisation d'une progressbar ?
    Par RiiiDD dans le forum Composants VCL
    Réponses: 6
    Dernier message: 08/09/2005, 11h28
  4. utilisation d'une ProgressBar
    Par knittel02 dans le forum C++Builder
    Réponses: 1
    Dernier message: 25/12/2004, 23h04
  5. [C#] Utilisation d'une ProgressBar pour un téléchargement
    Par snoof dans le forum Windows Forms
    Réponses: 10
    Dernier message: 04/10/2004, 19h37

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