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 :

Solutions possibles pour une application multi Form et multi Thread ?


Sujet :

Windows Forms

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 212
    Points : 146
    Points
    146
    Par défaut Solutions possibles pour une application multi Form et multi Thread ?
    Bonjour

    Je dois réaliser une application en C# avec 4 thread et dont chacun a son propre moyen de visualisation, donc chacun sa Form si possible.

    J'ai déja réalisé un application avec les thread pour faire du transfert de fichier avec des socket, mais les thread de reception de fichiers n'arrivaient pas à utiliser les controles de ma form :

    {"Opération inter-threads non valide*: le contrôle 'listBox1' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé."}

    J'aimerais donc savoir quels sont les moyens pour avoir les 4 Forms en même temps à l'écran, piloté par les 4 threads et comment les faires communiquer entre eux.

    Merci
    Passez de bonnes fêtes

  2. #2
    Expert confirmé
    Avatar de debug
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    1 034
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 034
    Points : 4 093
    Points
    4 093
    Par défaut
    Bonjour,

    Pour modifier les aspects graphiques d'un form depuis un thread il faut que tu utilises des délégués.
    May the Troll, be with you
    (Que le troll soit avec toi)

  3. #3
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Les 4 forms n'ont pas besoin d'être dans des threads distincts.

    Ici, ce dont tu as besoin, c'est de 4 threads métier et d'un seul thread graphique.

    Le message d'erreur que tu montres est dû au fait que seul le thread graphique a le droit de modifier les contrôles graphiques.

    Donc, si tu veux qu'une opération métier exécutée dans un autre thread soit visible dans l'UI, il faut que tes méthodes métier (ou des méthodes de ta form abonnées aux event de ces objets métier s'il y en a) passent par taForm.BeginInvoke(...).

    Cherche BeginInvoke et InvokeRequired dans la doc de la Form et sur ce forum, tu trouveras pas mal de discussions à ce sujet
    ಠ_ಠ

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 212
    Points : 146
    Points
    146
    Par défaut
    Délégué de classe

    Dans une classe de lycée en France, le délégué de classe est un élève de la classe chargé de représenter les autres élèves

    ============================================================

    Merci de ton aide debug

    Je vais donc lire ca pour pouvoir controler la form depuis un thread : Délégués http://msdn.microsoft.com/fr-fr/libr...71(VS.80).aspx

    Par contre, comme ne n'ai jamais fais de multi form en C#, je suis un peu perdu ...

    dans program.cs il charge la form d'origine et si j'en rajoute une autre il ne l'active que lorsqu'on ferme la premiere

    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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
     
    namespace MULTITHREAD
    {
        static class Program
        {
     
            /// <summary>
            /// Point d'entrée principal de l'application.
            /// </summary>
            ///
     
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new FORM1());
     
            }
        }
    }
    C'est donc ici que je dois créer mes Thread qui vont lancer les formes ?

    Dans un thread on lance la form de la même maniere ?

    Merci

  5. #5
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    salut

    Ya plusieurs solutions possibles bien sur

    Une solution "simple", est que au lancement de ton program, tu fais le Run() qui convient

    Et dans le Load de la form que tu vas "runner" ( bjr Céline ) tu pourras
    très bien lancé ce que tu veux !!!

    après, tu peux avoir un BackgroundWorker (ou un thread) par form, ou bien la solution mentionnée au dessus

    Perso, j'aime bien le concept Une Form / Un Thread comme cela, si tu dois rajouter d'autres formes à ton projet, il suffira que la forme ajoutée gère son comportement avec ou sans thread et basta

    Enfin, c'est une solution possible et simple à mettre en oeuvre
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 212
    Points : 146
    Points
    146
    Par défaut
    Vous avez des tutoriels qui utilise de genre de system ?

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 212
    Points : 146
    Points
    146
    Par défaut
    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.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using System.Threading;
     
    namespace PARKING_THREAD
    {
        class Program
        {
            /// <summary>
            /// Point d'entrée principal de l'application.
            /// </summary>
            ///
     
            [STAThread]
            public static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
     
                Thread Thread1;
                Thread1 = new Thread(new ThreadStart(Proc1));
                Thread1.Start();
     
                Thread Thread2;
                Thread2 = new Thread(new ThreadStart(Proc2));
                Thread2.Start();
     
                Thread Thread3;
                Thread3 = new Thread(new ThreadStart(Proc3));
                Thread3.Start();
            }
     
            public static void Proc1()
            {
                Application.Run(new BADGE2());
            }
     
            public static void Proc2()
            {
                Application.Run(new LECTEURS());
            }
     
            public static void Proc3()
            {
                Application.Run(new VISUALISATION());
            }  
        }
    }
    Pour le moment, ca ouvre bien les 3 forms en même temps

    Des suggestion ?

    Merci

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 217
    Points : 253
    Points
    253
    Par défaut
    Bonjour,

    Ce problème est un classique. A la différence des autres suggestions, que je ne discuterai pas, je ne remets pas en cause votre conception/code (à un détail près) et je me concentre plutôt sur l'exception .NET que votre appli prend "dans la figure" :

    Citation Envoyé par 6su7 Voir le message
    [...] mais les thread de reception de fichiers n'arrivaient pas à utiliser les controles de ma form :

    {"Opération inter-threads non valide*: le contrôle 'listBox1' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé."}
    [...]
    En fait, une appli .NET Winform, tot ou tard, delegue aux bonnes vieilles APIs Win32 de fenetrages. Or, tel que la partie Winforms .NET a été conçu, il convient de protéger les membres d'instances des classes utilisées en multi thread pour que .NET + Win32 "soient" content.

    Cela peut être fastidieux, car cela remet souvent en cause votre conception/implementation écrite la plupart du temps dans un esprit "mono-thread" ; donc, pour que vos forms communiquent gentiment en multi thread, via des gestionnaire d'evenements pour leurs controles, avec un code similaire au cas mono thread, mais sans prendre cette exception, le framework .NET vous propose "une pirouette" qui consiste à synchronizer (ou plutot serialiser) dans le thread principal .NET / Win32 de l'appli les echanges inter composants, en utilisant la propriété de la classe de base
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.Windows.Forms.Control
    et un delegue dédié à l' "invoke" (méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.Windows.Forms.Control.Invoke(...)
    ); voci le pattern de code, tiré de la doc du framework, mais adapté pour l'explication :

    (dans la form)

    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
     
            public delegate void MonEvenementDelegate(blabla, etc);
     
            private void MonEvenementSynchronizedHandler(blabla, etc)
            {
                // la, on fait le boulot effectif...
            }
     
            public void OnMonEvenement(blabla, etc)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new MonEvenementDelegate(this. MonEvenementSynchronizedHandler), blabla, etc);
                }
                else
                {
                    this.MonEvenementSynchronizedHandler(blabla, etc);
                }
            }
    bien sur, "blabla, etc" c'est la signature reelle utile de l'evenement du control dans votre cas de figure/votre conception.

    enfin, avec cette solution "simple", on fait l'hypothese que toutes les formes ont ete creees dans le meme thread : le thread principal, typiquement celui de la form principale créée dans le Main().

    'Hope it helps

  9. #9
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par 6su7 Voir le message
    Pour le moment, ca ouvre bien les 3 forms en même temps

    Des suggestion ?

    Merci
    Application.Run est fait pour lancer la form principale de l'appli.

    apres, pour lancer des "sous-fenetre", il vaut mieux faire comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FormBadge f = new FormBadge();
    f.Show();
    Code que tu peux mettre dans une methode que tu auras abonnee a l'evenement "Load" de ta form principale.

    Mais commencer un projet graphique ET multithread, ca fait beaucoup d'un seul coup a mon avis. Commence par un truc simple, puis ajoute un thread avec ton code a desynchroniser, parce qu'a mon avis tout d'un coup c'est trop

    Et comme l'evoquait theMonz, je t'invite a te renseigner sur la classe BackgroundWorker, qui est precisement faite pour gerer de l'asynchronisme simple dans les interfaces graphiques.
    ಠ_ಠ

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 212
    Points : 146
    Points
    146
    Par défaut
    Bonjour

    Merci a tous pour vos réponses, j'étudie toutes les propositions

    Control.CheckForIllegalCrossThreadCalls = false;

    C'est utilisable ca, ou pas recommandé ?

    Merci

  11. #11
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Points : 434
    Points
    434
    Par défaut
    Si je ne m'abuse, cela revient à désactiver le contrôle des threads, donc, à créer une faille de sécurité dans ton appli. Je pense qu'il vaut mieux se plier à la petite gymnastique des délégués.
    La sécurité de l'emploi
    "Ce n’est pas une pratique médicale sensée que de risquer sa vie en se soumettant à une intervention probablement inefficace afin d’éviter une maladie qui ne surviendra vraisemblablement jamais."
    Docteur Kris Gaublomme, médecin belge ("Vaccins et maladies auto-immunes")

  12. #12
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    salut

    le checkforIllegal... c'est pour les flemmards (moi, j'aime bien)

    Mais c'est pas très propre d'un point de vue conception...

    Après, parfois quand le temps manque, zapper ce controle peut te permettre d'arriver plus vite au résultat cherché... Mais en pratique, il serait mieux au final de passer par un vrai solution avec les invoke (et invokeRequired )

    Maintenant, tu peux te satisfaire de cela le temps de te focaliser sur d'autres parties

    Mais comme le fait remarquer très justement Guulh, il serait peut-etre plus raisonnable de travailler partie par "partie".... pour éviter trop d'éparpillement !!!
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  13. #13
    Expert éminent
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Points : 7 660
    Points
    7 660
    Par défaut
    Citation Envoyé par theMonz31 Voir le message
    le checkforIllegal... c'est pour les flemmards (moi, j'aime bien)
    Et c'est surtout uniquement valable en cours de débogage. Tu auras toujours une exception lorsqu'une application est démarrée en dehors du débogueur.
    Pas de questions techniques par MP

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 212
    Points : 146
    Points
    146
    Par défaut
    Ok je passerais par les délégé

  15. #15
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 217
    Points : 253
    Points
    253
    Par défaut
    Citation Envoyé par theMonz31 Voir le message
    [...]
    Mais comme le fait remarquer très justement Guulh, il serait peut-etre plus raisonnable de travailler partie par "partie".... pour éviter trop d'éparpillement !!!
    J'irais en ce sens moi aussi. En matière de développement logiciel, lors de la résolution des problèmes (analyse, conception, implémentation, etc) ce qui nous sauve "la vie" à tous, c'est le bon vieux motto : "diviser pour régner."

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 212
    Points : 146
    Points
    146
    Par défaut
    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
    public partial class Form1 : Form
        {
            Thread Test;
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                Test = new Thread(remplir);
                Test.Start();
            }
     
            void remplir()
            {
                textBox1.BeginInvoke((MethodInvoker)delegate {textBox1.Text = "hello world de thread";});
     
            }
        }

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

Discussions similaires

  1. conseils pour une application multi-fenêtres
    Par p1xl_01 dans le forum C#
    Réponses: 14
    Dernier message: 25/05/2010, 15h29
  2. Test automatisé pour une application Windows Forms
    Par Mat_76 dans le forum Windows Forms
    Réponses: 0
    Dernier message: 07/08/2009, 15h37
  3. Quelle solution pour une application web "temps réel"?
    Par izguit dans le forum Général Conception Web
    Réponses: 3
    Dernier message: 27/03/2008, 11h04
  4. Réponses: 2
    Dernier message: 27/11/2007, 10h07
  5. Splash Form pour une application VB.NET
    Par hrihan dans le forum Windows Forms
    Réponses: 8
    Dernier message: 08/09/2007, 22h24

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