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 :

Visual Studio 2005 - debug thread


Sujet :

Windows Forms

  1. #1
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut Visual Studio 2005 - debug thread
    Bonjour à tous,

    J'ai conçu un programme qui contient un thread devant mettre à jour l'interface en fonction de son travail. Bref, c'est bizarre parcequ'à chaque fois que je débug (pas à pas), Visual Studio 2005 (SP1) *freeze* pour 10 secondes, ensuite il me permet de jumper à la ligne suivante et ensuite mon thread meurt sans savoir pourquoi.

    Alors je me suis dit, pourquoi pas repartir un projet vide et y exécuter le même code au plus simple possible afin de vérifier si ce problème existe. Et c'est le cas !

    Visual Studio freeze entre l'exécution ces deux lignes (// *******).

    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
     
    public partial class Form1 : Form
    {
        private Thread m_Thread = null;
     
        public Form1()
        {
            InitializeComponent();
        }
     
        private void Form1_Load(object sender, EventArgs e)
        {
     
        }
     
        private static void UpdateFirmware(object param)
        {
            Form f = (Form1)param; // *******
     
            // Simple test pour le pas à pas
            int k = 0;      // *******
            k = k + 2;
        }
     
        private void button1_Click(object sender, EventArgs e)
        {
            m_Thread = new Thread(new ParameterizedThreadStart(UpdateFirmware));
            m_Thread.IsBackground = true;
            m_Thread.Start(this); // *******
        }
    }
    Toutefois, j'ai remarqué que le problème n'existe pas si je ne passe pas *this* en paramètre au Thread.

    Comme par exemple, ce bout de code fonctionne très bien en debug :

    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
    private static void UpdateFirmware(object param)
    {
        int k = (int)param;
     
        // Simple test pour le pas à pas
        int k = 0;
        k = k + 2;
    }
     
    private void button1_Click(object sender, EventArgs e)
    {
        m_Thread = new Thread(new ParameterizedThreadStart(UpdateFirmware));
        m_Thread.IsBackground = true;
        m_Thread.Start(4);
    }
    Est-ce que j'ai louppé quelque chose ? Je ne comprend pas trop. Je dois bien passé *this* en paramètre si je veux mettre à jour mon interface (avec un BeginInvoke évidemment). J'ai pas trop envie de passer une structure avec tous les contrôles à mettre à jour, ça sera long pour rien. À moins que je n'aie pas le choix.

    Merci
    Mieux vaut ne rien savoir que beaucoup savoir à moitié !
    Faite vous en pas avec la vie, personne en est sortie vivant !

  2. #2
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Je viens d'essayer avec une structure pour y passer un simple TextBox et le problème est le même.

    J'ai quand même trouvé ce qui cause le problème et comment le solutionner de façon temporaire pour mon projet.

    Voir les adresses suivantes :
    http://social.msdn.microsoft.com/For...a-f892635f7833

    http://blogs.msdn.com/greggm/archive...18/494648.aspx

    Ce qui est le plus étrange, c'est que je ne dois pas être le premier programmeur .NET à créer un thread, lui passer la référence d'une fenêtre en paramètre et ensuite mettre à jour ses controles durant le processus du thread ???

    Vous n'avez jamais rencontré ce problème au paravant ? Peut-être que je m'y prend mal... J'attend vos commentaires
    Mieux vaut ne rien savoir que beaucoup savoir à moitié !
    Faite vous en pas avec la vie, personne en est sortie vivant !

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    il est possible que ton thread connaisse le form sans le passer en paramètre

    il suffit de faire une classe, instanciée par le thread principal et qui prend en paramètre le form, le range dans une variable privée
    puis appeler une sub de cette classe qui instancie un thread, qui accède à la variable privée
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    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 Erakis Voir le message
    Ce qui est le plus étrange, c'est que je ne dois pas être le premier programmeur .NET à créer un thread, lui passer la référence d'une fenêtre en paramètre et ensuite mettre à jour ses controles durant le processus du thread ???
    Tu n'es pas le premier à essayer, non

    Mais en winforms, seul le thread associé à la form a le droit de modifier son contenu. C'est pour ça que le composant BackGroundWorker a été créé : il s'occupe de créer un thread exécutant ton code business, et balance des events dans le thread de la form, auxquels tu peux abonner des méthodes qui pourront sans souci tripatouiller ta form.
    Je t'invite à te documenter à son sujet sur la MSDN ou ici-même, où le sujet a été de maintes fois abordé.
    ಠ_ಠ

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    je pense qu'il peut s'en sortir sans backgroundworker, meme si en effet il encapsule tout ce qui est nécessaire à du multithreading ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    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
    Il peut s'en sortir, oui, mais c'est par pour autant qu'il pourra mettre à jour son UI à partir de ce nouveau thread
    ಠ_ಠ

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    oui mais il précise qu'il sait qu'il faut invoker (ou begininvoker) pour modifier l'ui
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    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 Pol63 Voir le message
    oui mais il précise qu'il sait qu'il faut invoker (ou begininvoker) pour modifier l'ui
    oups, t'as raison

    (rattrapage aux branches de l'extrême) raison de plus d'utiliser le BGW, au moins on se pose pas de question
    ಠ_ಠ

  9. #9
    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
    La lenteur de réaction est peut être liée au "func eval". En gros, le débogueur va chercher à appeler la méthode ToString du formulaire à un moment, alors que tu te trouves dans le thread non UI, ce qui va le bloquer quelques secondes.

    Pour éviter ça, tu peux ajouter un attribut DebuggerDisplay à ta classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [System.Diagnostics.DebuggerDisplay("Form1")]
    public partial class Form1 : Form
    {
        ...
    }
    Pas de questions techniques par MP

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    Citation Envoyé par StormimOn Voir le message
    La lenteur de réaction est peut être liée au "func eval". En gros, le débogueur va chercher à appeler la méthode ToString du formulaire à un moment, alors que tu te trouves dans le thread non UI, ce qui va le bloquer quelques secondes.

    Pour éviter ça, tu peux ajouter un attribut DebuggerDisplay à ta classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [System.Diagnostics.DebuggerDisplay("Form1")]
    public partial class Form1 : Form
    {
        ...
    }

    pas sur ...
    je viens de regarder cet attribut que je ne connaissais pas et à priori il ne sert qu'en debuggage ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    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 Pol63 Voir le message
    je viens de regarder cet attribut que je ne connaissais pas et à priori il ne sert qu'en debuggage ...
    C'est bien le problème justement
    Citation Envoyé par Erakis
    Bref, c'est bizarre parce qu'à chaque fois que je débug (pas à pas), Visual Studio 2005 (SP1) *freeze* pour 10 secondes,
    Ou alors j'ai raté quelque chose. Mais je ne pense pas car je connais bien ce problème et j'étais heureux lorsque j'ai trouvé la solution ^^
    Pas de questions techniques par MP

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    je me suis mal exprimé, donc je cite ca sera plus clair

    Determines how a class or field is displayed in the debugger variable windows.
    donc la fenetre d'espion express je pense (ou celle qui se déroule automatiquement en laissant le curseur sur une variable)

    ce qui est diffiérent du pas à pas sans regarder de variable ... enfin je pense
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  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
    J'ai retrouvé l'article qui parlait de ça (ça date un peu). Ce sera plus simple. En tout cas pas besoin d'afficher la fenêtre d'espion ou autre pour avoir le problème.
    Pas de questions techniques par MP

  14. #14
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Citation Envoyé par StormimOn Voir le message
    J'ai retrouvé l'article qui parlait de ça (ça date un peu). Ce sera plus simple. En tout cas pas besoin d'afficher la fenêtre d'espion ou autre pour avoir le problème.
    Si l'on jette un coup d'oeil à mon deuxième post, j'avais déjà mentionné ce lien et un autre parlant de mon problème. J'avoue que moi aussi j'ai eu un immense soulagement en trouvant la solution hier soir ! J'étais découragé

    C'est réellement relié à l'évaluation des propriétés de la form. Il faut simplement désactiver cette fonction soit par le menu Options/Debugging/General ("Enable property evaluation and other implicite calls".

    Ou encore utiliser l'attribut suivant sur la class de ma form :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [System.Diagnostics.DebuggerDisplay("Form1")]
        public partial class Form1 : Form
    Pour ce qui est du Background Worker, j'étais déjà au courant de son existance. Cependant, comme je suis un programmeur C++ MFC, j'ai toujours été habitué à envoyer des SendMessage pour faire mes mises à jour de l'UI. Bref, depuis la version .NET 1.0, j'ai toujours procéder 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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public partial class Form1 : Form
    {
        delegate void UpdateTextBoxDelegate(TextBox tb, string txt);
     
        private Thread m_Thread = null;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.TextBox textBox1;
     
        public Form1()
        {
            InitializeComponent();
        }
     
        public static void UpdateTextBox(TextBox tb, string txt)
        {
            if (!tb.InvokeRequired)
            {
                tb.Text = txt;
            }
            else 
            {
                tb.BeginInvoke(new UpdateTextBoxDelegate(UpdateTextBox), new object[] { tb, txt });
            }
        }
     
        private static void ThreadFct(object param)
        {
            Form1 f = (Form1)param;
            UpdateTextBox(f.textBox1, "Bonjour");
        }
     
        private void button1_Click(object sender, EventArgs e)
        {
            m_Thread = new Thread(new ParameterizedThreadStart(ThreadFct));
            m_Thread.IsBackground = true;
            m_Thread.Start(this);
        }
    }
    Si j'ai bien compris le fonctionnement du BackgroudWorker, je dois faire mes mise à jour de l'UI dans l'événement 'WorkerReportsProgress' ? Et le code étant dans cet événement serait exécuté à partir du Thread de ma Form donc, je n'aurais pas à faire d'Invoke ?

    Merci
    Mieux vaut ne rien savoir que beaucoup savoir à moitié !
    Faite vous en pas avec la vie, personne en est sortie vivant !

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    le backgroundworker est plutot pratique
    il y a un évènement qui est appelé quand on veut démarrer le traitement (doword je crois)
    celui ci est sur un thread séparé, il suffit d'y coder le traitement
    il a 2 autres qui eux sont ramenés sur le thread principal (en fait ils en sont jamais parti quand on regarde dans reflector)
    il y en a un pour rapporter la progression et l'autre pour dire que c'est fini
    celui pour la progression, on peut passer les paramètres qu'on veut
    donc soit une progression, soit des données à afficher carrément (voir meme les 2 en meme temps et plus)
    pour que cet évènement soit appelé il y a une méthode sur le backgroundworker à appeler
    celui de la fin, je ne sais plus si on peut passer des paramètres

    et il y a une méthode cancelasync, qui ne fait que flagger un booléen, booléen qu'on doit ensuite tester dans le traitement (en général une boucle où on regarde à chaque tour), s'il est flaggé on peut faire en sorte que ca s'arrete proprement

    je crois qu'on peut aussi gérer un pool avec (définir le nombre maxi en meme temps, le reste est queué) enfin ca reste à vérifier
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 26/03/2012, 14h27
  2. [Visual Studio 2005 Debug]Problème de debug
    Par Astraya dans le forum Visual Studio
    Réponses: 1
    Dernier message: 12/02/2009, 10h53
  3. Debug avec Emulator CE 5.0 (x86) et Visual Studio 2005
    Par atone81 dans le forum Windev Mobile
    Réponses: 0
    Dernier message: 09/02/2009, 09h59
  4. Réponses: 2
    Dernier message: 10/11/2008, 09h05
  5. Remote Debugging avec Visual Studio 2005
    Par bibifoc dans le forum Windows Forms
    Réponses: 2
    Dernier message: 19/03/2008, 16h11

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