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 :

[C#] Instancier un objet Form depuis un Thread


Sujet :

Windows Forms

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 11
    Points : 13
    Points
    13
    Par défaut [C#] Instancier un objet Form depuis un Thread
    Bonjour,

    Je travail avec Visual studio 2003.
    Dans mon projet, j'ai un thread qui s'occupe de recevoir de l'information sous forme de string. Je voudrais, à la réception d'un message, ouvrir une fenêtre qui affichera le message reçu.

    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
                    private void creation_Threadecoute()
    		{
    			this.monThread = new Thread(new ThreadStart(threadEcoute));
    			this.monThread.Name="threadEcoute";
    			this.monThread.Start();
    		}
    		private void threadEcoute()
    		{
    			continuer = true;
    			string data;
    			while(continuer)
    			{
    				/* réception du message dans data qui utilise un ReadLine 
    				qui bloque le thread jusqu'à la réception d'un message */
    				//création d'un Form
    				Erreur err = new Erreur(data);
    				err.Show();
    			}
    		}
    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
    public class Erreur : System.Windows.Forms.Form
    	{
    		private System.Windows.Forms.Label label1;
    		private System.Windows.Forms.Button button1;		
    		private System.ComponentModel.Container components = null;
    		public Erreur(string msg)
    		{			
    			InitializeComponent();
    			this.label1.Text = msg;			
    		}		
    		private void InitializeComponent()
    		{
    			this.label1 = new System.Windows.Forms.Label();
    			this.button1 = new System.Windows.Forms.Button();
    			this.SuspendLayout();
    			// 
    			// label1
    			// 
    			this.label1.Location = new System.Drawing.Point(24, 16);
    			this.label1.Name = "label1";
    			this.label1.Size = new System.Drawing.Size(240, 72);
    			this.label1.TabIndex = 0;
    			// 
    			// button1
    			// 
    			this.button1.Location = new System.Drawing.Point(104, 104);
    			this.button1.Name = "button1";
    			this.button1.TabIndex = 1;
    			this.button1.Text = "Ok";
    			this.button1.Click += new System.EventHandler(this.button1_Click);
    			// 
    			// Erreur
    			// 
    			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
    			this.ClientSize = new System.Drawing.Size(292, 133);
    			this.Controls.Add(this.button1);
    			this.Controls.Add(this.label1);
    			this.Name = "Erreur";
    			this.Text = "Erreur";
    			this.ResumeLayout(false);
    		}
    		private void button1_Click(object sender, System.EventArgs e)
    		{
    			this.Close();
    		}
    	}
    Quand la fenêtre Erreur s'ouvre, elle se "bloque", elle plante jusqu'à ce que je ferme la fenêtre Principal qui à créé le thread (qui implique le kill du thread).

    Est-ce que ce serait possible, depuis le thread, de créer la fenêtre Erreur comme je le désire et qu'elle s'exécute normalement? Est-ce que la création d'un nouvel objet Form n'est pas équivalent à la création d'un nouveau thread et donc que ce nouveau thread s'execute indépendemment du reste?

    Merci d'avance
    A toute

    Philip.

  2. #2
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    Je pense que le problème vient du fait que le show est dans une boucle ou la main n'est jamais rendue au système donc dans ce thread, aucune gestion d'évènement ne peut avoir lieu. L'instanciation est-elle blocante ?
    • Si non, ajoute un doevents. Mais faire un show à chaque itération . Mieux serait d'afficher la fenêtre avant et de changer le contenu d'un label via une propriété.
    • Si oui, affiche la fenêtre dans un nouveau thread.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 11
    Points : 13
    Points
    13
    Par défaut
    Salut

    Citation Envoyé par jab
    L'instanciation est-elle blocante ?
    la fenêtre met le thread en pause le temps de son existence? Si c'est ça, non elle ne le fait pas.


    Je pourrais créer un thread qui va créer une fenêtre Erreur et qui s'arretera après?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    private void creation_ThreadErreur()
    		{
    			Thread this.monThreadErr = new Thread(new ThreadStart(threadErreur));
    			this.monThread.Start();
    		}
    		private void threadErreur()
    		{
    			Erreur err = new Erreur(data);
    			err.Show();			
    		}

    Si je fais exécuter ce code depuis le threadEcoute, j'aurai ma fenetre qui pourra tourner seul? Je vais aller essayer. Mais, est-ce qu'il n'y aurait pas une solution plus courte / simple ?

    edit : pour cette solution, quand le threadErreur à fini de s'exécuter, la fenêtre Erreur qu'il a créé est fermée. Les doEvents je ne connais pas, c'est les événements? ActionListener etc.?

  4. #4
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    Oui tu peux comme je te l'ai proposer, faire le show avant la boucle et dans la boucle, changer l'affichage via une propriété. Tu rajoute la méthode DoEvents() en fin de boucle pour permettre à l'appli de géréer les évèneemnt.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 11
    Points : 13
    Points
    13
    Par défaut
    J'ai essayé de créer l'objet Erreur avant d'entrer dans le Thread.

    Pour pouvoir afficher une fenêtre Erreur lorsque je reçois un message, il faut que je fasse, dans le thread:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      this.fenetreErreur.getlabel().Text = "corps du message à afficher";
      this.fenetreErreur.Show();
    Il faudrait aussi que j'associe à l'action de fermer cette fenêtre l'action de la cacher et non pas la fermer completement, sinon je devrai en recréer une.

    Bon, est-ce que ça devrait fonctionner? J'ai regardé un exemple de programme qui utilise des threads. Je pense que c'est plus ou moins la même chose que mon programme, mais mon programme ne veut pas afficher les fenêtres correctement.

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    private void creation_Threadecoute()
    		{
    			fenetreerreur = new Erreur("vide");
     
     
    			this.monThread = new Thread(new ThreadStart(threadEcoute));
    			this.monThread.Name="threadEcoute";
    			this.monThread.Start();
    		}
    		private void threadEcoute()
    		{
    			continuer = true;
    			string data;
    			while(continuer)
    			{
     
    				try
    				{
    					Console.WriteLine("Attente d'un message du serveur depuis le thread");
    					data = this.monform1.getConnect().GetFromServer().ReadLine();
     
     
    					char [] parama = {' '};
    					string [] srvrep = data.Split(parama, 500);
     
    					//gestion des messages réponses
    					if(srvrep[0].Equals("-ERR"))
    					{
    						//gestion des erreurs
    						this.fenetreerreur.getlabel().Text = "Gestion des erreurs";
    						this.fenetreerreur.Show();
     
    					}
    					else if(srvrep[0].Equals("+OK"))
    					{
    						//gestion des confirmations
    						this.fenetreerreur.getlabel().Text = "Gestion des confirmations";
    						this.fenetreerreur.Show();
     
     
    						//receptionMessage()
    					}
    						//réceptions de msg divers
    					else if(srvrep[0].Equals("MESG"))
    					{
    						Conversation uneconv = new Conversation(monform1, srvrep[1]);
    					}
    					else if(srvrep[0].Equals("SRV_ADDCONTACT"))
    					{
    						Confirmcontact unconfirmcontact = new Confirmcontact(this.monform1.getConnect(), srvrep[1]);
    						unconfirmcontact.Show();
    					}
    					this.fenetreerreur.getlabel().Text = data;
    					this.fenetreerreur.Show();
     
     
     
    					Console.WriteLine("msg recu: " + data);
     
     
     
    				}
    				catch(Exception)
    				{
    					/*Erreur err = new Erreur("erreur du thread: thread tente de tourner en étant pas connecté");
    					err.Show();*/
     
    					continuer = false; //on arrete le thread
    					this.Close(); //on ferme la fenetre principale
    					this.monform1.Show(); //on remontre la fenetre de login
    				}
    				Thread.Sleep(100);
     
    			}
    Voila mon code, je pense qu'il me manque une grosse partie de la théorie sur la POO et les threads, si quelqu'un veut bien m'orienter vers un bon tuto ou quelque chose qui pourrait m'aider, et bien merci d'avance.

    Sinon avec ce que je viens d'écrire je pense que je pourrais trouver tout seul.
    Philip.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Points : 621
    Points
    621
    Par défaut
    Il suffit peut être d'utiliser ShowDialog() à la place de Show() pour afficher la fenêtre d'erreur.

  7. #7
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    As tu regardé mon article, http://jab.developpez.com/tutoriels/...ess/synchrone/
    je fais à peu près la même chose avec un ShowDialog dans un thread séparé.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 11
    Points : 13
    Points
    13
    Par défaut
    Je n'avais pas pensé à utiliser ShowDialog(). Comme les intérfaces simples sont faciles à faire en c#, on a tout de suite créer notre propre fenêtre d'information.

    Merci, j'étais tombé sur le tuto oui, mais je m'étais contenté de lire la partie sur Invoke(). C'est encore compliqué comme tutorial pour moi mais je vais le lire.

    Salut !

  9. #9
    DrQ
    DrQ est déconnecté
    Membre expérimenté
    Avatar de DrQ
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    388
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 388
    Points : 1 515
    Points
    1 515
    Par défaut
    Je ne pense pas que le problème vienne de la fenêtre mais plus du fait que le listener est bloquant et du coup bloque la boucle évènementielle de ta fenêtre qui est liée au thread.

    Tu peux faire évoluer ton code de la façon suivante :

    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
     
            private void creation_Threadecoute()
            {
                this.monThread = new Thread(new ThreadStart(threadEcoute));
                this.monThread.Name="threadEcoute";
                this.monThread.Start();
            }
            private void threadEcoute()
            {
                continuer = true;
                string data;
                while(continuer)
                {
                    /* réception du message dans data qui utilise un ReadLine 
                    qui bloque le thread jusqu'à la réception d'un message */
                    //création d'un Form
                    Erreur err = new Erreur(data);
                    Thread oThreadShowErreur(new ThreadStart(err.Show));
                    oThreadShowErreur.Start();
                }
            }
    Je ne pas sûr à 100% que cela fonctionne mais ça devrait. Par contre ATTENTION au nombre de message que tu peux avoir, car le nombre de threads possibles par le système est limité. Après peut être intégré un ThreadPool pour éviter une surcharge en threads du système.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 11
    Points : 13
    Points
    13
    Par défaut
    Et bien ça ne fonctionne toujours pas.
    La différence avec ta solution DrQ, c'est que la fenêtre s'affiche puis sa cache instentanément. Elle ne reste pas bloquée donc.

    Est-ce normal qu'après l'avoir affichée, elle se cache toute seul?

    Je crée la fenêtre erreur hors du thread, je l'affiche à l'intérieur de la boucle du thread, puis quand on arrive au début de la boucle au
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Console.WriteLine("Attente d'un message du serveur depuis le thread");
    Elle se referme (sans raison?)

    Je vais lire le tuto


    Edit: Je suis désolé pour tous ces messages puisqu'on m'avait parlé de ShowDialog(), et je n'avais pas essayé. Je pensais que cela ouvrait une fenêtre de windows (comme en javascript, et dans tous les langages pratiquements dailleurs... Les ConfirmDialog etc...). J'ai finalement testé en lisant le tutorial et je ne sais par quel miracle, ça fonctionne .
    Ma solution finale alors est:

    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
    private void creation_Threadecoute()
    		{
    			this.monThread = new Thread(new ThreadStart(threadEcoute));
    			this.monThread.Name="threadEcoute";
    			this.monThread.Start();
    		}
    		private void threadEcoute()
    		{
    			continuer = true;
    			string data;
    			while(continuer)
    			{
    				Console.WriteLine("Attente d'un message du serveur depuis le thread");
    				data = this.monform1.getConnect().GetFromServer().ReadLine();
    				fenetreerreur = new Erreur("vide");
    				this.fenetreerreur.getlabel().Text = data;					
    				this.fenetreerreur.ShowDialog();
    			}
    		}
    Il y a cependant un grand inconvénient à cette solution: tant que je n'ai pas fermé la fenêtre, le thread n'écoute plus. Pfiou je suis perdu, je comprends petit à petit. Il faut que je cherche du côté de la solution en utilisant un thread je pense.

    Merci beaucoup pour votre aide
    Bonne journée et à une prochaine fois
    Philip.

  11. #11
    DrQ
    DrQ est déconnecté
    Membre expérimenté
    Avatar de DrQ
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    388
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 388
    Points : 1 515
    Points
    1 515
    Par défaut
    Arf vi, désolé c'est ma faute. Dans ma solution essaie avec un ShowDialog plutot que le Show.

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 30/04/2015, 00h51
  2. Instancier un objet page depuis son nom "maPage.aspx"
    Par tontonks dans le forum ASP.NET
    Réponses: 8
    Dernier message: 16/08/2010, 18h27
  3. [Thread] Modifier objet static depuis thread
    Par orelero dans le forum Concurrence et multi-thread
    Réponses: 4
    Dernier message: 19/04/2006, 18h09
  4. Réponses: 1
    Dernier message: 25/03/2006, 18h53
  5. Réponses: 4
    Dernier message: 08/03/2006, 20h07

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