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# 2.0]Thread externe mais bloquant main interface


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 82
    Par défaut [C# 2.0]Thread externe mais bloquant main interface
    Bonjour,

    je situe le contexte.
    j'ai une application fonctionnant sur le principe des plugins.
    c'est a dire que j'ai un MAIN, qui charge et affiche des modules, ces modules étant des DLL.

    dans une de ces DLL, je fais un traitement, long qui touche a l'interface graphique du module.

    je procède comme suit :

    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
     
            private void btnOpenFile_Click(object sender, EventArgs e)
            {
                try
                {
                    ThreadStart threadDelegate = new ThreadStart(ThreadLoadingFile);
                    Thread newThread = new Thread(threadDelegate);
                    newThread.Start();
                }
                catch (Exception E)
                {
                    throw new Exception(E.Message);
                }
            }
     
     
     
            private void ThreadLoadingFile()
            {
                try
                {
                    if (this.InvokeRequired)
                    {
                        this.EndInvoke(BeginInvoke(new MethodInvoker(delegate() { this.ThreadLoadingFile(); })));
                    }
                    else
                    {
                        LoadFile();
                        PrepareText(); // traitement le plus long;
                        MessageBox.Show("TRAITEMENT FINI !");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
     
            }
    ce code tourne très bien , mais pendant , l'exécution du sois-disant "Thread" , toute l'interface de mon écran reste figé, et je ne peux plus interagir avec l'interface. Je dois attendre la fin du traitement.
    A quoi est-ce due ? est du au fait que ce soit une DLL ...

    Merci d'avance de votre aide.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Août 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2003
    Messages : 835
    Par défaut
    Non c'est dû au fait que le code de ThreadLoadingFile se contente de demander au thread principal de faire le boulot (BeginInvoke) tout simplement. Donc en gros ton thread secondaire ne sert à rien.

    Les BeginInvoke sont à réserver pour modifier des contrôles de l'interface, pas pour faire l'ensemble des traitements.

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    une fois j'ai remarqué qu'un thread secondaire touchant aux objets visuels du thread principal ralentissait biein le shmilblick, alors que le thread principal faisait ca rapidement, essaye de transférer la partie graphique sur le thread principal, au moins à des fins de test
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 82
    Par défaut
    donc , il n'existe aucun autre moyen de mettre ces fonctions en thread...
    en utilisant autre chose que des begininvoke en endinvoke ?

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    il faut que tu separes les traitements de la mise à jour de l'interface graphique :
    - fais le traitement dans le thread newThread
    - pour la mise à jour de l'interface, utilise BeginInvoke
    Si tu fais tout avec BeginInvoke, c'est le thread principal qui fait tout le boulot...
    Oui, je sais, je paraphrase un peu la réponse de Sphax

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 82
    Par défaut
    ok, je comprend.
    mais juste encore une chose.
    D'après ce que j'en ai lu, sur le net, le BeginInvoke et invoke servent à pouvoir acceder a partir d'un thread à un autre control qui se trouve dans un autre thread.
    si je dois mettre le traitement qui touche a l'interface (graphique) , également, dans le thread principal, alors BeginInvoke et invoke, ne servent pas à grand chose.

  7. #7
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    moi quand je fais du multithreading c'est pas avec begininvoke
    mais avec new thread(addressof sub)
    et ca marche bien

    pour en plus que les thread aient accès aux objets des autre thread il faut faire
    me.checkforillegalcross quelquchose = false
    mais comme je disais ca m'avait ralenti une fois donc j'ai laissé une partie du traitement sur le thread principal
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    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
    Salut,

    il faudrait voir du coté des plugins, pour "invoker" uniquement quand necessaire. J'imagine que si le traitement est long, le plugin doit faire des traitements non entierement dependant de l'UI (attaquer une BDD, travailler sur le net ou autres). Il faut faire un begininvoke à ce moment la, dans le plugin, (ou alors cacher l'invoke en appellant une methode intermediaire qui invokerait si besoin est), comme ca tu gardes deux threads concurrents, et une UI, qui bien que chargeant des infos, reste reactive.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 4
    Par défaut
    Psykotik,

    D'abord, gardes bien à l'esprit que tu as un thread dit principal, qui est en fait le thread UI. Lui seul peut accéder aux éléments de l'interface graphique. Si ce thread effectue un travail de traitement long, l'interface freeze car le thread UI est occupé et ne peut plus effectuer le traitement des événements tels que clic de souris, etc ...

    Les autres threads ne peuvent absolument pas toucher aux éléments graphiques.

    L'idée est dès lors, pour qu'un autre thread puisse modifier l'UI, que celui-ci demande au thread UI d'effectuer le boulot à sa place. Ceci se fait en utilisant le méthode BeginInvoke.

    Dans ton code, tu demandes en fait au thread UI d'exécuter la fonction ThreadLoadingFile(). C'est bien car c le thread UI qui touche à l'interface, mais c'est mal car c'est aussi lui fait tout le boulot.

    Comme le dit sphax : ton thread ne sert à rien du tout.


    A mon avis, le mieux est de garder une bonne séparation entre le traitement UI et le traitement métier en procédant ainsi : ton plugin/dll devrait émettre des événements à ton projet principal (tu es alors toujours dans le thread de la dll), qui appellerait des fonctions destinée à toucher à l'UI en utilisant BeginInvoke( c alors le thread UI qui prend le relais, uniquement pour le traitement de l'interface).

    je te conseille également d'utiliser la classe BackgroundWorker pour simplifier ta gestion des threads.

    J'espère que ceci aura pu t'aider.

Discussions similaires

  1. [Thread] Détruit, mais jamais 'nil'
    Par Riskmaker dans le forum API, COM et SDKs
    Réponses: 9
    Dernier message: 04/08/2008, 13h41
  2. problème simple mais bloquant
    Par marianna dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 13/05/2008, 14h31
  3. adresse mail marche en externe mais pas en interne
    Par topino dans le forum Outlook
    Réponses: 5
    Dernier message: 16/04/2008, 17h54
  4. Thread et fonctions bloquantes
    Par sebome dans le forum Général Python
    Réponses: 2
    Dernier message: 13/09/2007, 21h57
  5. Réponses: 5
    Dernier message: 16/12/2005, 18h41

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