Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème interthread avec les sockets

je déteste ça :S

Sujet résolu
    8 mars 2012 à 17:41:39

    Salut,

    Donc voilà comment mon logiciel fonctionne :
    - Envoi des données de connexion
    - Reception si c'est OK ou pas
    - Si c'est OK on affiche une group box (groupBoxXXX.Visible = true;)

    Et bien quand je reçois mes données OK et que j'essaie d'afficher la group box, le programme se ferme tout de suite !
    Problème d'accès interthread, ou l'accès à l'objet spécifié n'est pas avec le thread avec lequel il a été créer.
    Le problème c'est que même si le logiciel plante quand je le débug avec VS, VS ne m'affiche pas d'erreur. Mais je suppose que c'est à cause de ça.

    Alors voilà, si quelqu'un peut m'expliquer comment faire pour faire des opérations interthread avec des objets windows form (ou autre) ce serai cool ;)

    Merci d'avance !
    • Partager sur Facebook
    • Partager sur Twitter
      8 mars 2012 à 17:43:22

      La question est posée régulièrement sur le forum... :-°

      Passe par la méthode Invoke() de ta Form, et ça ira mieux.
      • Partager sur Facebook
      • Partager sur Twitter
        8 mars 2012 à 17:50:46

        J'ai chercher et j'ai pas trouver.

        Merci pour la réponse ^^

        Mais je comprend pas comment utiliser Invoke ? pour lancer la form tout au début je dois faire Invoke ?

        Si tu sais m'expliquer vite fais stp :S

        Merci encore !
        • Partager sur Facebook
        • Partager sur Twitter
          8 mars 2012 à 18:01:33

          Supposons que lorsque ton socket reçoit un message (dans un thread dédié donc), tu veuilles exécuter une méthode qui modifie l'état de ta Form (ou d'un de ses contrôles). Au lieu d'appeler cette méthode directement, il faut que tu appelles la méthode Invoke de ta Form en lui passant la méthode en paramètre, et Invoke se chargera de l'exécuter dans le thread principal pour éviter le problème d'accès cross-thread. :)
          • Partager sur Facebook
          • Partager sur Twitter
            8 mars 2012 à 18:08:19

            Par exemple ceci : Invoke(listBox1.Visible = true); ne fonctionne pas ^^
            et ça : Invoke(System.Delegate, listBox1.Visible = true); non plus ^^

            listBox1.Invoke(listBox1.Visible, true); ça non plus .

            Je comprends pas bien désolé :s

            J'ai compris ! je pense ^^
            private delegate void UpdateLabelDelegate ( string text );
            // ****************
            private UpdateLabelDelegate m_upLbl;
            


            et pour l'appel de la fonction :
            label_Affichage.Invoke(m_upLbl, args);
            
            • Partager sur Facebook
            • Partager sur Twitter
              8 mars 2012 à 18:20:37

              Citation : guiedo

              Par exemple ceci : Invoke(listBox1.Visible = true); ne fonctionne pas ^^


              En effet, car listBox1.Visible = true n'est pas une méthode mais une instruction.

              Par contre () => listBox1.Visible = true est une méthode (sous la forme d'une expression lambda), donc Invoke(() => listBox1.Visible = true); fonctionnera (moyennant peut-être un casting en Action, j'ai un doute tout-à-coup).

              En réalité l'utilisation d'une expression lambda :
              Invoke(() => listBox1.Visible = true);
              
              est une écriture raccourcie pour l'utilisation d'une méthode anonyme :
              Invoke(delegate()
              {
                  listBox1.Visible = true;
              });
              
              qui est elle-même une écriture raccourcie pour l'utilisation d'une vraie méthode :
              // parmi les méthodes de ta Form :
              private void ShowListBox()
              {
                  listBox1.Visible = true;
              }
              
              //...
              // à la réception d'un message : 
              Invoke(ShowListBox);
              

              donc ça revient bien à créer une méthode avec ton code et à la transmettre à Invoke. :)
              • Partager sur Facebook
              • Partager sur Twitter
                8 mars 2012 à 18:30:00

                Merci c'est parfait :)

                et je peux faire ça sans soucis ? ->


                private void ShowListBox()
                {
                    listBox1.Visible = true;
                    lsitBox2.Visible = true;
                }
                



                AH NON ! Oublie ! de toute façon ça marche pas ^^ aucun de tes codes fonctionnent
                • Partager sur Facebook
                • Partager sur Twitter
                  8 mars 2012 à 18:33:39

                  Bien entendu, c'est une méthode comme les autres ;)

                  Cela dit on utilisera plus généralement une méthode anonyme pour éviter de créer des méthodes dont le seul but est de passer par Invoke :
                  Invoke(delegate()
                  {
                      listBox1.Visible = true;
                      lsitBox2.Visible = true;
                      //... ce que tu veux
                  });
                  

                  Citation

                  aucun de tes codes fonctionnent


                  Tu es sûr de les avoir placés au bon endroit ? :-°
                  • Partager sur Facebook
                  • Partager sur Twitter
                    8 mars 2012 à 18:38:02

                    Je l'ai mis à l'intérieur d'une fonction.

                    En gros :



                    class MaClasse
                    {
                       private void MaFonction()
                       {
                          Invoke(delegate()
                          {
                              listBox1.Visible = true;
                              lsitBox2.Visible = true;
                              //... ce que tu veux
                           });
                       }
                    
                       private void ReceptionDataSocket()
                       {
                          // gestion des données reçues etc
                          // si on reçois les données correctes
                          MaFonction();
                       }
                    }
                    
                    • Partager sur Facebook
                    • Partager sur Twitter
                      8 mars 2012 à 18:39:33

                      Et MaFonction(), tu l'appelles quand? :-°
                      • Partager sur Facebook
                      • Partager sur Twitter
                        8 mars 2012 à 18:41:26

                        Dans une autre ^^ mais le probleme c'est que VS me balance une erreur donc je saurai meme pas tester si ça marche ^^

                        Impossible de convertir méthode anonyme en type 'System.Delegate', car il ne s'agit pas d'un type délégué
                        • Partager sur Facebook
                        • Partager sur Twitter
                          8 mars 2012 à 18:45:45

                          Citation : guiedo

                          Dans une autre ^^


                          C'est justement ça qui est intéressant, donc il faudrait que tu nous montres ça aussi...

                          Citation : guiedo

                          Impossible de convertir méthode anonyme en type 'System.Delegate', car il ne s'agit pas d'un type délégué


                          Ok, c'est le casting nécessaire que j'évoquais tout-à-l'heure et que j'oublie toujours. Ca passera mieux avec ça :

                          Invoke((Action)delegate()
                          {
                              listBox1.Visible = true;
                              lsitBox2.Visible = true;
                              //... ce que tu veux
                          });
                          

                          C'est dû au fait que Invoke() est une vieille méthode des WinForms datant d'avant l'introduction de la généricité et des méthodes anonymes, donc la conversion d'un delegate en System.Delegate n'est pas implicite. Oui, c'est con. :-°
                          • Partager sur Facebook
                          • Partager sur Twitter
                            8 mars 2012 à 18:53:19

                            Citation : Orwell

                            C'est justement ça qui est intéressant, donc il faudrait que tu nous montres ça aussi...


                            Voilà j'ai éditer ^^

                            Citation : Orwell

                            Ok, c'est le casting nécessaire que j'évoquais tout-à-l'heure et que j'oublie toujours. Ca passera mieux avec ça :



                            ça marche tout de suite mieux :D
                            Merci beaucoup Orwell !

                            Je vais rentrer tout ça dans ma bibliothèque de code source :p
                            • Partager sur Facebook
                            • Partager sur Twitter
                              8 mars 2012 à 18:57:31

                              Citation : guiedo

                              Voilà j'ai éditer ^^


                              Ok, mais alors (sauf raison particulière) écris plutôt ça comme ça :

                              class MaClasse
                              {
                                 private void MaFonction()
                                 {
                                     listBox1.Visible = true;
                                     lsitBox2.Visible = true;
                                     //... ce que tu veux
                                 }
                              
                                 private void ReceptionDataSocket()
                                 {
                                    // gestion des données reçues etc
                                    // si on reçois les données correctes
                                    Invoke(MaFonction);
                                 }
                              }
                              

                              Ca sera d'autant plus simple. ;)
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Problème interthread avec les sockets

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown