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

C# Discussion :

Delegate et Thread


Sujet :

C#

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 44
    Points : 101
    Points
    101
    Par défaut Delegate et Thread
    Bien le bonsoir,

    je suis étudiant en deuxième année de BTS IRIS, et je viens donc poster mon premier message sur ce forum pour venir chercher de l'aide à mon problème.

    Je dois d'ici la fin de l'année, pour mon diplôme, coder la simulation de capteurs et d'actionneurs pour une maquette de traitement de surface qui n'en possède donc pas. Ayant découvert l'usine à gaz qu'est Visual Studio, j'ai décider de lâcher mon vieux Borland c++ v6 (), et de m'attaquer au .NET de Microsoft.
    Etant un fervent utilisateur du c++, j'ai commencé avec une "solution" (comme ils disent) en c++/cli.
    Au début, tout allait bien, le côté "managé" du .NET ne me dérangeait pas plus que ça, je m'y suis fait assez rapidement (avec une aide précieuse de vos FAQ ).
    Et là, c'est la cata', il me fallait utiliser une certaine dll pour communiquer avec le module (Labjack pour ceux qui connaissent) qui me relie à la maquette: le mélange de type natifs et managés dans les mêmes classes m'a donné du fil à retordre,au point où j'ai décider de passer en C#.

    Et à mon grand étonnement, plus de problème, la dll version .NET du Labjack était encore plus simple d'utilisation, problème résolu ...
    Ou presque

    Comme je l'ai préciser plus haut, vos FAQ m'ont beaucoup aidées, et surtout en ce qui concerne les threads et les delegate.
    La syntaxe étant à peine différente du c++/cli, j'ai eu aucune peine à faire la transformation.

    Mon premier test consiste donc à mettre à jour un pauvre petit label selon si j'arrive, oui ou non, à établir une connexion au module Labjack, et tout cela depuis un thread.
    Cela marche parfaitement une, deux, trois, ... x fois. En raccourcissent un peu le code à chaque fois, me rendant compte de quelques lignes inutiles ou ne me servant plus.
    Puis arrive le moment fatidique, après un nouveau test sur ce même thread, qui a fonctionner. J'ai voulu modifié la visibilité de la déclaration de mon delegate (protected à public) car le compilo me crié dessus (un avertissement et pas une erreur)pour mettre la même visibilité à la déclaration de mon type delegate et à la déclaration du delegate (les deux en public). J'effectue donc la modification, je relance mon application et là, c'est le "drame". Le thread ne fait plus son boulot, le label ne se met plus à jour.
    J'ai tout de suite remodifier la précédente manip', pour retrouver au caractère près un code qui avait fonctionner, il y a un build de cela.
    Mais plus rien n'y fait, j'ai beau bidouiller dans tout les sens, rajouter des Console.WhriteLine() de partout pour voir où ça clochait. J'ai même recommencer un nouveau projet, en effectuant un copier/coller de mes fichiers, au cas où un fichier de configuration, quelque part, ne se serait pas endommagé ou autre ...
    Le label ne se met toujours pas à jour et je commence à péter un câble

    Je vous en serait reconnaissant de bien vouloir m'aider, voici les morceaux de code concernés.

    TdsForm.cs
    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
    75
    76
    77
    78
    79
    80
    81
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
     
    namespace TdsSimulation
    {
        public partial class TdsForm : Form
        {
            /* --------------------------------------------------------------*/
            /* ------ Attributs ---------------------------------------------*/
            private TdsThread paramThread;
     
            private Thread Connexion;
            //private Thread CapteursTemperature;
            //private Thread CapteursNiveau;
     
            public delegate void errorLabelDelegateHandler(int error);
            public errorLabelDelegateHandler errorLabelDelegate;
            /* --------------------------------------------------------------*/
            /* ------ Constructeur et Destructeur ---------------------------*/
            public TdsForm()
            {
                InitializeComponent();
                this.paramThread = new TdsThread(this);
            }
            /* --------------------------------------------------------------*/
            /* ------- Méthodes des composants graphiques -------------------*/
            private void connectionButton_Click(object sender, EventArgs e)
            {
                this.Connexion = new Thread(new ThreadStart(this.paramThread.Open));
                this.Connexion.Start();
                Thread.Sleep(3000);
            }
            /* --------------------------------------------------------------*/
            private void modeButton_Click(object sender, EventArgs e)
            {
                // this.CapteursTemperature = new Thread(new ThreadStart(this.paramThread.
            }
            /* --------------------------------------------------------------*/
            private void modeComboBox_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (this.modeComboBox.SelectedIndex == 0)
                    this.modeLabel.Text = "Aucune intéraction n'est \npossible sur le système.";
                if (this.modeComboBox.SelectedIndex == 1)
                    this.modeLabel.Text = "Vous pouvez intéragir sur \nles capteurs et les actionneurs.";
            }
            /* --------------------------------------------------------------*/
            /* ------- Méthodes des delegate --------------------------------*/
            public void updateErrorLabel(int error)
            {
                try
                {
                    if (error == 0)
                    {
                        this.errorImg.Image = global::TdsSimulation.Properties.Resources.erreur1;
                        this.errorLabel.Text = "Connexion au\n labjack réussie";
                        throw new Exception("Modification réussie.");
                    }
                    if (error == 1)
                    {
                        this.errorImg.Image = global::TdsSimulation.Properties.Resources.erreur0;
                        this.errorLabel.Text = "Erreur lors \nde la connexion";
                        throw new Exception("Modification non réussie.");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
            /* --------------------------------------------------------------*/
        }
    }
    TdsThread.cs

    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace TdsSimulation
    {
     
        class TdsThread
        {
            /* --------------------------------------------------------------*/
            /* ------ Attributs ---------------------------------------------*/
            private TdsLabjack myLJ;
            private TdsForm myPtr;
            /* --------------------------------------------------------------*/
            /* ------ Constructeur et Destructeur ---------------------------*/
            public TdsThread(TdsForm ptr)
            {
                this.myLJ = new TdsLabjack();
                this.myPtr = ptr;
            }
            /* --------------------------------------------------------------*/
            /* ------- Méthodes ---------------------------------------------*/
            public void Open()
            {
                try
                {
                    if (this.myLJ.Connection())
                    {
                        Console.WriteLine("Connection réussie");
                        this.myPtr.Invoke(this.myPtr.errorLabelDelegate, 0);
                        throw new Exception("Après réussite.");
                    }
                    else
                    {
                        Console.WriteLine("Connection échec");
                        this.myPtr.Show();
                        this.myPtr.Invoke(this.myPtr.errorLabelDelegate, 1);
                        throw new Exception("Après l'erreur.");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    Console.WriteLine("Connection echec");
                }
            }
            /* --------------------------------------------------------------*/
        }
    }
    TdsLabjack.cs

    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using LabJack.LabJackUD;
     
    namespace TdsSimulation
    {
     
        class TdsLabjack
        {
            /* --------------------------------------------------------------*/
            /* ------ Attributs ---------------------------------------------*/
            private int LJ_Handle;
     
            /* --------------------------------------------------------------*/
            /* ------ Constructeur et Destructeur ---------------------------*/
            public TdsLabjack(){...}
            /* --------------------------------------------------------------*/
            /* ------- Méthodes ---------------------------------------------*/
            public bool Connection()
            {
                try
                {
                    LJUD.OpenLabJack(LJUD.DEVICE.U3, LJUD.CONNECTION.USB, "", true, ref this.LJ_Handle);
                    return true;
                }
                catch (LabJackUDException e)
                {
                    Console.WriteLine(e);
                    return false;
                }
            }
            /* --------------------------------------------------------------*/
            public void Get_Orders(){...}
            /* --------------------------------------------------------------*/
            public void Send_Values(int Temp, int Level){...}
            /* --------------------------------------------------------------*/
        }
    }
    Merci d'avoir pris le temps de lire mon pâté où je raconte ma vie, et n’hésitez pas à me demander certains détails qu'y vous aurez peut être échappés.
    En vous remerciant d'avance.

    Cordialement o/

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2006
    Messages : 197
    Points : 279
    Points
    279
    Par défaut
    Tu devrais utiliser le InvokeRequired avec un Invoke si tu modifie l'interface graphique qui elle se trouve dans un thread.

    La mise à jour de l'UI n'étant pas forcément disponnible au moment ou ton thread passe dans la méthode.

    http://msdn.microsoft.com/en-us/libr...(v=vs.90).aspx

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 44
    Points : 101
    Points
    101
    Par défaut
    Bonsoir

    Je te remercie pour ta réponse demonia, j'ai essayé de mettre ça en place dans le fichier TdsForm.cs :

    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
     
    namespace TdsSimulation
    {
        public partial class TdsForm : Form
        {
            /* --------------------------------------------------------------*/
            /* ------ Attributs ---------------------------------------------*/
            private TdsThread paramThread;
     
            private Thread Connexion;
            //private Thread CapteursTemperature;
            //private Thread CapteursNiveau;
     
            public delegate void errorLabelDelegateHandler(int error);
            public errorLabelDelegateHandler errorLabelDelegate;
            /* --------------------------------------------------------------*/
            /* ------ Constructeur et Destructeur ---------------------------*/
            public TdsForm()
            {
                InitializeComponent();
                this.paramThread = new TdsThread(this);
            }
            /* --------------------------------------------------------------*/
            /* ------- Méthodes des composants graphiques -------------------*/
            private void connectionButton_Click(object sender, EventArgs e)
            {
                this.Connexion = new Thread(new ThreadStart(this.paramThread.Open));
                this.Connexion.Start();
                Thread.Sleep(3000);
            }
            /* --------------------------------------------------------------*/
            private void modeButton_Click(object sender, EventArgs e)
            {
                // this.CapteursTemperature = new Thread(new ThreadStart(this.paramThread.
            }
            /* --------------------------------------------------------------*/
            private void modeComboBox_SelectedIndexChanged(object sender, EventArgs e)
            {...}
            /* --------------------------------------------------------------*/
            /* ------- Méthodes des delegate --------------------------------*/
            public void updateErrorLabel(int error)
            {
                try
                {
                    if (error == 0)
                    {
                        if (this.errorLabel.InvokeRequired && this.errorImg.InvokeRequired)
                        {
                            errorLabelDelegateHandler d = new errorLabelDelegateHandler(updateErrorLabel);
                        }
                        else
                        {
                            this.errorImg.Image = global::TdsSimulation.Properties.Resources.erreur1;
                            this.errorLabel.Text = "Connexion au\n labjack réussie";
                        }
                    }
                    if (error == 1)
                    {
                        if (this.errorLabel.InvokeRequired && this.errorImg.InvokeRequired)
                        {
                            errorLabelDelegateHandler d = new errorLabelDelegateHandler(updateErrorLabel);
                        }
                        else
                        {
                            this.errorImg.Image = global::TdsSimulation.Properties.Resources.erreur0;
                            this.errorLabel.Text = "Erreur lors \nde la connexion";
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
            /* --------------------------------------------------------------*/
        }
    }
    J'ai surement loupé quelque chose, vu que ça ne fonctionne toujours pas

    Ou alors ma syntaxe est fausse quant au InvokeRequired ...

    Je vais essayer de modifier mon code dans le fichier TdsThread.cs pour voir

    En vous remerciant encore d'avance pour m'aider à trouver une solution

  4. #4
    Membre éprouvé
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Points : 1 177
    Points
    1 177
    Par défaut
    Il faut bien comprendre le coup du InvokeRequiered (couplé aux méthodes Invoke ou mieux encore BeginInvoke).
    Code c# : 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
        public void updateErrorLabel(int error)
        {
          // Si on n'est pas dans le thread principal
          if (InvokeRequired)
          {
            // On invoque la même méthode de manière asychrone avec l'argument donné
            BeginInvoke(new Action<int>(updateErrorLabel), error);
     
            // On peut aussi invoquer la même méthode mais de manière synchrone :
            // Invoke(new Action<int>(updateErrorLabel), error);
          }
          else
          {
            // Étant dans le bon thread (le principal)
            // On fait ce que l'on veut avec l'IHM
            switch (error)
            {
              case 0:
                  this.errorImg.Image = global::TdsSimulation.Properties.Resources.erreur1;
                  this.errorLabel.Text = "Connexion au\n labjack réussie";          
                break;
              case 1:
                  this.errorImg.Image = global::TdsSimulation.Properties.Resources.erreur0;
                  this.errorLabel.Text = "Erreur lors \nde la connexion";
              break;
            }
          }

  5. #5
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 44
    Points : 101
    Points
    101
    Par défaut
    Merci pour cette réponse instructive neilbgr
    J'ai un peu de mal avec les exemples de msdn.

    Mais ça bloque toujours pour l'update du label

    J'ai remarqué autre chose. Après avoir parsemé quelques Console.WhriteLine() ici et là dans mes deux autres classes TdsThread et TdsLabjack ... La console parle d'elle même.

    TdsThread
    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using LabJack.LabJackUD;
     
    namespace TdsSimulation
    {
     
        class TdsThread
        {
            /* --------------------------------------------------------------*/
            /* ------ Attributs ---------------------------------------------*/
            private TdsLabjack myLJ;
            private TdsForm myPtr;
            /* --------------------------------------------------------------*/
            /* ------ Constructeur et Destructeur ---------------------------*/
            public TdsThread(TdsForm ptr)
            {
                this.myLJ = new TdsLabjack();
                this.myPtr = ptr;
            }
            /* --------------------------------------------------------------*/
            /* ------- Méthodes ---------------------------------------------*/
            public void Open()
            {
                try
                {
                    Console.WriteLine("Debut de la méthode Open()");
                    if (this.myLJ.Connection() != LJUD.LJUDERROR.NOERROR)
                    {
                        Console.WriteLine("Retour false de la méthode Connection()");
                        this.myPtr.Invoke(this.myPtr.errorLabelDelegate, 1);
                    }
                    else
                    {
                        Console.WriteLine("Retour true de la méthode Connection()");
                        this.myPtr.Invoke(this.myPtr.errorLabelDelegate, 0);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
            /* --------------------------------------------------------------*/
        }
    }
    TdsLabjack
    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
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using LabJack.LabJackUD;
     
    namespace TdsSimulation
    {
     
        class TdsLabjack
        {
            /* --------------------------------------------------------------*/
            /* ------ Attributs ---------------------------------------------*/
            private int LJ_Handle;
            private LJUD.LJUDERROR LJ_error;
            /* --------------------------------------------------------------*/
            /* ------ Constructeur et Destructeur ---------------------------*/
            public TdsLabjack(){...}
            /* --------------------------------------------------------------*/
            /* ------- Méthodes ---------------------------------------------*/
            public LJUD.LJUDERROR Connection()
            {
                try
                {
                    Console.WriteLine("Début de la méthode Connection()");
                    this.LJ_error = LJUD.OpenLabJack(LJUD.DEVICE.U3, LJUD.CONNECTION.USB, "", true, ref this.LJ_Handle);
                    return this.LJ_error;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    return this.LJ_error;
                }
            }
            /* --------------------------------------------------------------*/
            public void Get_Orders(){...}
            /* --------------------------------------------------------------*/
            public void Send_Values(int Temp, int Level){...}
            /* --------------------------------------------------------------*/
        }
    }
    Console
    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
     
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities.Sync\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.Sync.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Debugger.Runtime\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Debugger.Runtime.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Users\Alex\documents\visual studio 2012\Projects\TdsSimulation\TdsSimulation\bin\Debug\TdsSimulation.vshost.exe' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\assembly\GAC_MSIL\LJUDDotNet\3.32.0.0__9d6c109908595016\LJUDDotNet.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml.Linq\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.Linq.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.DataSetExtensions\v4.0_4.0.0.0__b77a5c561934e089\System.Data.DataSetExtensions.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.CSharp\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.CSharp.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Deployment\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Deployment.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll' chargé
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_fr_b77a5c561934e089\mscorlib.resources.dll' chargé
    Le thread 'vshost.NotifyLoad' (0x9e8) s'est arrêté avec le code 0 (0x0).
    Le thread '<Sans nom>' (0xe30) s'est arrêté avec le code 0 (0x0).
    Le thread 'vshost.LoadReference' (0x1100) s'est arrêté avec le code 0 (0x0).
    'TdsSimulation.vshost.exe' (Managé (v4.0.30319))*: 'C:\Users\Alex\documents\visual studio 2012\Projects\TdsSimulation\TdsSimulation\bin\Debug\TdsSimulation.exe' chargé, symboles chargés.
    Une exception de première chance de type 'LabJack.LabJackUD.LabJackUDException' s'est produite dans LJUDDotNet.dll
    Debut de la méthode Open()
    Début de la méthode Connection()
    LabJack not found
    Le code à l'intérieur de mon if/else, dans la classe TdsThread, ne s’exécute pas, et donc l'update du label Pourtant, aucune exception n'est levée ...

    En vous remerciant encore d'avance

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2006
    Messages : 197
    Points : 279
    Points
    279
    Par défaut
    Soit tu as une exception, soit la méthode connection ne finit pas son exécution correctement.
    Il y a le message "LabJack not found".
    Est-ce qu'il vient d'une autre partie du code?

    Mais le fait que le console.write suivant ne s'affiche pas correctement pourrait aussi venir du fait que comme tu travail avec des thread, le thread principal pourrait se terminer avant que l'autre n'ait terminé l'exécution de son code.
    Une connexion de périphérique étant longue, ça pourrait expliquer ton problème.
    Tu as plusieurs solutions pour empêcher ça.

    http://stackoverflow.com/questions/1...inish-with-net

    Et si tu travail avec du .net 4.0 ou 4.5 tu peux aussi utiliser les tasks et te servir du Task.WaitAll.

    Ici tu as un exemple pour l'utilisations de plusieurs tasks et un waitAll qui attend la fin de l'exécution des différentes tasks.
    http://msdn.microsoft.com/fr-fr/libr...v=vs.100).aspx

  7. #7
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 44
    Points : 101
    Points
    101
    Par défaut
    Le "Labjack not found" est dû au fait que j'étais chez moi à ce moment là, je n'avais pas le labjack sous la main. C'est le Console.WriteLine() dans le bloque catch de ma fonction Connection qui l'affiche.

    Mais le truc, c'est que j'ai l'impression, qu'il n’exécute pas le return qui est aussi dans le bloque catch de cette même fonction, quand le Labjack est introuvable ou quand il y a un problème dans les paramètres de connexion au Labjack.
    Et dans ce cas, il ne rentre même pas dans le bloque if/else.

    Deuxièmement, j'ai encore rajouté des Console.WriteLine(), et quand la connexion s'effectue sans problème, le processus rentre bien dans le bloque if/else, mais l'Invoke ne s’exécute pas (ou alors, il n'a pas le temps, comme tu me l'a fait remarquer, mais ça m'étonnerai, j'y ai aussi rajouter des Console.WriteLine tout du long de la méthode delegate, mais aucun ne s'affiche, encore une fois ...)

    TdsThread.cs
    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
     
    class TdsThread
        {
            /* --------------------------------------------------------------*/
            /* ------ Attributs ---------------------------------------------*/
            private TdsLabjack myLJ;
            private TdsForm myPtr;
            private string str_error;
            /* --------------------------------------------------------------*/
            /* ------ Constructeur et Destructeur ---------------------------*/
            public TdsThread(TdsForm ptr)
            {
                this.myLJ = new TdsLabjack();
                this.myPtr = ptr;
            }
            /* --------------------------------------------------------------*/
            /* ------- Méthodes ---------------------------------------------*/
            public void Open()
            {
                try
                {
                    Console.WriteLine("Debut de la méthode Open()");
     
                    str_error = this.myLJ.Connection();
                    if (str_error == "LabJack not found")
                    {
                        Console.WriteLine("Retour false de la méthode Connection()");
                        this.myPtr.Invoke(this.myPtr.errorLabelDelegate, 1, str_error);
                        Console.WriteLine("Fin de la méthode updateLabelError()");
                    }
                    else
                    {
                        Console.WriteLine("Retour true de la méthode Connection()");
                        this.myPtr.Invoke(this.myPtr.errorLabelDelegate, 0, str_error);
                        Console.WriteLine("Fin de la méthode updateLabelError()");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
            /* --------------------------------------------------------------*/
        }
    J'ai encore modifié le retour de Connection() pour l'afficher sur mon IMH au lieu de mes précédents messages "Connexion réussie/échouée".

    Mon code, lors d'une connexion réussie, le processus exécute la ligne 33, mais n'effectue pas le reste.

    Ps: Oui, je travaille sous Vs 2012, donc avec .Net 4.5, merci pour les liens, je regarde ça.

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2006
    Messages : 197
    Points : 279
    Points
    279
    Par défaut
    Petite précision, tu ne devrais pas invoquer le delegate depuis ton thread mais appeler la méthode updateErrorLabel(int).

    Si tu as suivi le code de neilbgr, le invokeRequired et le invoke sont gérés par cette méthode.

    En gros, tu vas appeler la méthode updateErrorLabel qui va vérifier si le thread de ton UI est disponible.
    S'il l'est, il va afficher le message ou faire les modifs sur l'UI.
    S'il ne l'est pas, il va lancer l'invoke ou le BeginInvoke.

    Je te donne un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void addLine(DataGridViewRow dgvr) {
    	// Vérifie si un invoke est requis
    	if (dataGridView1.InvokeRequired) {
    		// Créé ton callback qui va rappeler la méthode addLine en lui envoyant le même paramètre.
    		AddLineCallback d = new AddLineCallback(addLine);
    		this.Invoke(d, new object[] { dgvr });
    	} else {
    		// s'il n'y a pas besoin de callback ou que le thread est disponible il va faire la modification sur ton UI.
    		dataGridView1.Rows.Add(dgvr);
    	}
    }
    delegate void AddLineCallback(DataGridViewRow dgvr);
    et quand je veux rajouter quelque chose dans ce datagrid, il me suffit d'appeler la méthode directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DataGridViewRow dgvr = new DataGridViewRow();
    // ....
    addLine(dgvr);
    Ta méthode qui contient l'invoke est auto-suffisante si on peut dire.
    C'est elle-même qui va savoir s'il y a besoin d'un invoke et qui va se rappeler elle-même.

    c'est exactement le même principe avec le BeginInvoke.

  9. #9
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 44
    Points : 101
    Points
    101
    Par défaut
    Ça fonctionne enfin, un grand merci demonia

    Avant de mettre résolu, j'ai une dernière petite question quant au déroulement du thread.

    Console:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // ...
    Debut de la méthode Open()
    Début de la méthode Connection()
    Le thread '<Sans nom>' (0x8b8) s'est arrêté avec le code 0 (0x0).
    Retour true de la méthode Connection()
    Début de la méthode delegate updateErrorLabel
    Position: thread secondaire
    Fin de la méthode updateLabelError()
    Début de la méthode delegate updateErrorLabel
    Position: thread principal
    Switch 0
    On voit avec la console que dans un premier temps, on est encore dans le thread secondaire, et à ce moment, on voit que l'on sort de la méthode updateLabelError, grâce au console.WriteLine("Fin de la méthode updateLabelError()") qu'il y a après l'appel de la méthode.
    Puis on rentre à nouveau dans la méthode, et on arrive donc dans le thread principal, et les modifications sur l'IHM se passent correctement.

    Est ce que j'ai bien compris ?

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2006
    Messages : 197
    Points : 279
    Points
    279
    Par défaut
    oui c'est ça.
    l'UI est dans ton thread principal.
    Pour éviter que ton UI freeze à chaque grosse exécution de code, on utilise des thread secondaires ou des backgroundworkers pour exécuter du code.

    Par contre, pour faire des modifications sur ton UI, il faut repasser dans ton thread principal (faire communiquer tes thread en gros) d'où l'invoke. (si j'ai bien compris la question)

  11. #11
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 44
    Points : 101
    Points
    101
    Par défaut
    Tu as bien compris la question, merci encore

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

Discussions similaires

  1. [Débutant] delegate et thread
    Par Harrychoco dans le forum C#
    Réponses: 2
    Dernier message: 15/05/2013, 17h10
  2. Croisements de threads / Fonctionnement des "delegate"
    Par Fabllot dans le forum C++/CLI
    Réponses: 3
    Dernier message: 18/07/2007, 13h18
  3. [C#][Thread][Invoke] petit problème de delegate
    Par clinic dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 22/06/2007, 12h38
  4. [C# 2.0][Form]Comment utiliser les Delegates & Threading
    Par Tips dans le forum Windows Forms
    Réponses: 8
    Dernier message: 08/01/2006, 15h22
  5. [C#]Thread, event/delegate et Form
    Par doccpu dans le forum Windows Forms
    Réponses: 28
    Dernier message: 01/08/2005, 19h35

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