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 :

Fenetre.show() apparaît puis disparait


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 113
    Par défaut Fenetre.show() apparaît puis disparait
    Salut , je réalise en ce moment un petit software de messagerie instantanée et j'ai un petit soucis que je vais essayer de vous exposer.

    j'ai donc une classe server.cs qui écoute les connections entrantes

    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
    public void run()
            {       
                while (true)
                {
                    try
                    {
                        Socket clientSocket = sockeServ.Accept();
                        ThreadContact tc = new ThreadContact(clientSocket);
                        tc.messageEvent += new      ThreadContact.MessageEventHandler(tc_messageEvent);
                        Thread caller = new Thread(new ThreadStart(tc.run));
                        caller.Start();
                    }
                    catch(SocketException s)
                    {
     
                    }
                }
            }
            public void tc_messageEvent(object sender, MessageArrivedEvent e)
            {
                if (e != null) messageEvent(this, e);
     
            }
    Ensuite j'ai une classe threadContact qui récupere les messages entrant, toujours dans un thread pour ne pas bloquer les autres connections entrantes.

    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
     
    public void run()
            {
     
               // NetworkStream ns = new NetworkStream(socket);
     
                 byte[] bytes = new byte[256];
     
                // Get reply from the server.
                 socket.Receive(bytes);
                 MessageArrivedEvent e = new MessageArrivedEvent(Encoding.UTF8.GetString(bytes),socket);
                 if (e != null)
                 {
                     messageEvent(this, e);
                 }
            }
    Donc en gros, sur les deux bouts de code précédents, lorsqu'une personne se connecte à moi, je lance un autre Thread (ThreadContact) pour récuperer les messages, et ensuite, forcément, j'utilise le système d'évènements-delegate pour renvoyer ce message à ma classe carnet, ceci explique cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     if (e != null)
                 {
                     messageEvent(this, e);
                 }
    bref je pense que vous avez capté, y a rien d'extraordinaire.

    Donc maintenant d'un point de vue fonctionnel, une fois que j'ai récupéré ce foutu message dans ThreadContact, je dois le renvoyer à ma classe carnet grâce aux évènements ( ce que je réussis à faire), et il me reste à vérifier, une chose:

    LA fenêtre de conversation est-elle déjà ouverte???????

    et bien vous l'aurez deviner, dans le cas que je chercher à gerer elle n'est pas ouverte.
    Donc voici un extrait de mon code Carnet.cs pas très complexe:

    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
    public void tc_messageEvent(object sender, MessageArrivedEvent e)
            {
                if (e != null)
                {
                    MessageBox.Show("coucou" + e.EventText);
                    openOrFocusWindow(e);
                }
            }
    public void openOrFocusWindow(string msg)
    {
    //si fenetre pas encore ouverte
    if (instanceFenetreDejaOuverte==null)
                {
                    //si fenetre non encore ouverte
                     ctArrivant = new Contact();
                     ctArrivant.Pseudo = pseudoEm;
                     ctArrivant.Id = idContactEm;
     
                    //Ouverture d'une nouvelle fenêtre de conversation
                    Fenetre fn = new Fenetre(ContactConnect, ctArrivant, so);
                    fn.Carnet = this;
                    fn.showMsg.AppendText(ctArrivant.Pseudo + " a dit: " + messageFromXml);
                    fn.showMsg.AppendText("\n");
                    fn.Text = "Vous conversez avec : " + ctArrivant.Pseudo;
                    LesConversationsEnCours.Add(fn);
                    fn.Show();
                    fn.Focus();
                }
    }
    voilà dans dans le bout de code ci-dessus je récupère donc mon évènement, et j'appelle openOrFocusWindow(msg)

    et donc là je vois que ma fenêtre n'est pas encore ouverte, donc bon, j'en crée une nouvelle et je fais un fen.Show().

    Et bien, en mode debug je constate donc que la fenêtre s'ouvre bien pendant un instant, mais pas complètement, c'est-à dire que c'est tout blanc à l'intérieur , puis, ensuite lorsque je reviens dans la méthode run de ThreadContact, précisément ici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     if (e != null)
                 {
                     messageEvent(this, e);
                 }
    et bien apres l'avoir appellé elle disparait, snif!!!


    Cependant si je fais un ShowDialog() au lieu d'un Show(), ça marche mais ce n'est pas ce que je souhaite.

    Voilà si quelqu'un à une idée, n'hésitez pas car c'est un vrai casse tête

  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
    Bonjour mnemonic78,

    c'est normal, Show() n'est pas bloquant, ShowDialog() l'est car il incorpore sa propre pompe à message. Pour que ton show marche correctement, il faut lancer une boucle de message sur le thread qui à créer la fenetre (ton thread de reception ici), en faisant un appel à Application.Run(fn).

    Bon courage.

  3. #3
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 113
    Par défaut
    ok donc d'après toi au lieu de mettre Show(), j'ai juste à remplacer par Application.Run(fn)?


    Sinon j'ai une autre petite question?

    Que se passe t-il si je ferme une form ouverte avec un showDialog, un Show() ou ici avec un Run()???

    En debug, j'ai remarqué que mes fenêtres de discussion qui pour chacune incorpore un thread d'écoute, continuent à écouter même si elles ont été fermé, c'est assez problématique une fenêtre fermé, donc, qui n'est plus visible, mais qui vit encore!! Puisque à chaque fois je suis obligé de recréer un handle (handleCreate). Mais cependant, certaine fois, quand j'attend un moment, on m'affiche quand je veux creer le handle de la fenetre qui n'est plus visible, que je ne peux atteindre un objet supprimé.
    En conséquence j'en conclue que l'objet vit encore pendant un moment et est ensuite détruit, cela est encore plus problématique. Pourrais-tu m'éclairer sur ce point??

  4. #4
    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
    Quand tu clos une fenetre ouverte avec Run() ou Show() (donc une fenetre non modale), la fenetre sera disposée à sa fermeture, a contrario avec ShowDialog, elle ne l'est pas. Reafficher une fenetre disposée peut etre problematique. Le probleme de Show(), c'est que in fine, cela revient à faire Visible = true;, dans un contexte ou le thread appelant est deja pris dans une boucle, ca fait ce que l'on attend, mais si ce thread n'a pas de pompes à message, ca va afficher la fenetre un cour instant, mais le thread ne s'arretant pas pour traiter les messages, la fenetre va freezer ou devenir blanche, car le thread va se terminer, tu as un handle dans le vide que personne ne traite. Donc oui, des qu'on veut afficher une fenetre sur un thread, il faut s'assurer que Run ait été appelé au moins une fois, pour créer le contexte evenementiel.

    Il faut t'assurer qu'au moment du Dispose, ta fenetre va fermer toutes les ressources qu'elle aurait utilisé (pour eviter les problematiques de thread d'ecoutes survivants). Pour cela abonne toi à l'event Disposed de form, et gere la fermeture de ton ecoute.

    Bref, la destruction des objets ont en a rien à faire en .Net (la destruction dans l'absolu, c'est du release de memoire, ce n'est pas notre probleme), l'important est que tu puisses controler que ta form relache bien ton thread, et c'est la qu'il faut intervenir sur l'event Disposed pour stopper ce thread. L'objet va survivre, mais au moins les ressources hypothetiquement acquise ne t'embeteront pas.

    En esperant t'avoir aidé.

  5. #5
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 113
    Par défaut
    En mettant un Application.Run(fn) il me dit que le démarrage d'une deuxieme boucle de message sur un seul thread n'est pas valide!!!

    Je suis un peu perdu là, moi si j'utilise des Show() et non des ShowDialog () à la base, c'est pour que l'utilisateur puisse naviguer de fenêtre en fenêtre.

    qu'est-ce que l'event dispose ? quand-est-ce qu'il se déclenche?
    Disons que je m'abonne à l'event dispose et que dans cette méthode j'arrête le thread d'écoute. Le gars connecté à moi , m'enverra, alors des messages dans le vide puisque je n'écouterai plus sur la socket, le thread d'écoute sur celle-ci étant définitivement stoppé.

    Donc, je me dis, au lieu de fermer la fenêtre, lorsque l'utilisateur clique sur la croix, ne vaudrait-il pas mieux juste la cacher??? ne serait-ce pas plus simple comme fonctionnement et est ce que c'est possible en m'abonnant à l'event close(), de lui interdire de fermer la fenêtre mais de la cacher?? L'utilisateur croira qu'il l'a fermer , alors qu'en réalité elle est simplement cachée.
    Comme ça plus de problèmes de thread, ensuite j'aurai plus qu'a stocker toutes mes fenêtres cachées dans une liste et j'ai juste à les montrer quand l'utilisateur le souhaite.

  6. #6
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 113
    Par défaut
    Bon et bien après plusieurs heures de recherche sur des forums surtout anglais, j'ai l'impression que cette question de l'affichage de form avec la méthode Show() dans un thread est vraiment impossible et ça me fait vraiment Chxxx, c'est incroyable !! je vais être obligé d'utiliser ce fichu showDialog()!!.

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

Discussions similaires

  1. fenetre de connexion, puis rien
    Par Celano dans le forum Administration système
    Réponses: 1
    Dernier message: 01/06/2015, 17h29
  2. [DOM] Le texte apparait puis disparait
    Par Nasky dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 08/06/2007, 14h38
  3. Réponses: 10
    Dernier message: 03/11/2006, 18h39
  4. Réponses: 4
    Dernier message: 30/08/2005, 12h59

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