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 :

C# - multithread reception valeur vide


Sujet :

C#

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2014
    Messages : 4
    Points : 4
    Points
    4
    Par défaut C# - multithread reception valeur vide
    bonjour à tous, je rencontre des difficultés pour mon multi-thread avec les classe codeur et afficheur. Le problème que j'ai actuellement est que toutes les 100 milliseconde environ je récupère des informations sous forme de trame grâce à la classe noeud_can (envoyer_trame / recevoir_trame) pour la méthode CodeurValeur() de la classe Codeur.cs.
    Mais comme j'ai le thread de cette méthode et celle de l'afficheur (CodeurValeurAfficheur()), 1 fois sur 5 environ je ne reçoit pas de trame et donc je n'obtient pas de valeur.
    Je n'ai pas ce problème lorsque le thread du codeur fonctionne tout seul, sans celui de l'afficheur. Si je remet en place le thread de l'afficheur et que je le lance, le problème revient.

    --------------------------------------------------------------------------
    Classe Codeur.cs
    La valeur du capteur est 222
    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
    89
    90
    91
    92
    93
    94
    95
    class Codeur : noeud_can
        {
     
            //Variable témoin du lock.
            private static Object _lock = new Object();
     
            //Variable de contrôle.
            private bool _quitter = false;
     
            //Variable valeur pour afficheur
            public int ValeurCodeurFinal;
     
            public Codeur(string nom_peripherique, UInt16 numero_noeud)
                : base(nom_peripherique, numero_noeud)
            {
            }
     
     
     
            public void CodeurValeur(object capteur)
            {
                //Boucle infinie contrôlée.
                while (!_quitter)
                {
                    //On verouille l'accès aux variables tant que l'on a pas terminé.
                    lock (_lock)
                    {
                        Capteur grid = (Capteur)capteur;
                        if ((grid.ValeurCapteurFinal != 0))
                        {
     
                            #region Envoie et reception trame
                            //COB ID
                            uint COB_ID_emission_sdo = (uint)0x600 + numero_noeud; //0x600 trame SDO  cf manuel p668   + numero noeud (1)
                            uint COB_ID_reception_sdo = (uint)0x580 + numero_noeud; //0x580 trame SDO  cf manuel p668  + numero noeud (1)
     
                            Console.WriteLine("début de la capture");
                            //Envoie de la trame pour lire l'entrée analogique numéro 2 du variateur
                            //0x40 - requête de lecture d'un paramètre du variateur     64 en décimal    4 octets
                            //5cbd - Affichage des marques de repère actuelles du noyau Motion Control
                            // plage d'affichage du capteur : -214748.3647  a 214748.3647    voir page 1015 (C01210)    
                            // 0x3 - sous index 3:  affichage de la position -- réelle actuelle générée par un système codeur en option
                            envoyer_trame(COB_ID_emission_sdo, 8, 0x40, 0x45, 0x5b, 0x03, 0x0, 0x0, 0x0, 0x0);
                            //envoyer_trame(COB_ID_emission_sdo, 8, 0x40, 0xbd, 0x5c, 0x05, 0x0, 0x0, 0x0, 0x0);      -- ancienne version (moins précise)
                            Console.WriteLine("\nenvoi de la trame de lecture de la valeur d'entrée");
                            TPCANMsg message_reponse;
                            message_reponse = recevoir_trame(COB_ID_reception_sdo, 8);
                            //Thread.Sleep(400);
                            #endregion
     
     
                            #region Conversion reception trame
                            Thread.Sleep(100);
                            string disthexa = message_reponse.DATA[7].ToString("X2");
                            string disthexa2 = disthexa + message_reponse.DATA[6].ToString("X2");
                            string disthexa3 = disthexa2 + message_reponse.DATA[5].ToString("X2");
                            string disthexa4 = disthexa3 + message_reponse.DATA[4].ToString("X2");
     
                            int intAgain2 = int.Parse(disthexa4, System.Globalization.NumberStyles.HexNumber);
                            Console.WriteLine("La valeur de intAgain2 = {0}", intAgain2);
     
                            int tour = (intAgain2 / 10000 / 360);
                            //Divise le nombre par 10k car la valeur est mise à l'échelle  
                            //(Facteur de mise à l'échelle : 10000)  et division par 360 pour obtenir une valeur précise 
                            double tourcodeur = (tour * 0.2);  // 10 tour = 2 cm
                            double valeurcodeur = (tourcodeur * 10.0);
                            int theValueToConvert = Convert.ToInt32(valeurcodeur);
                            Console.WriteLine("\n\n\tNombres de tours : {0}", tour);
                            Console.WriteLine("\tnombres de centimètres : {0}", tourcodeur);
                            #endregion
     
                            #region Valeur pour afficheur (calcule)
     
                            this.ValeurCodeurFinal = (grid.ValeurCapteurFinal - theValueToConvert);
                            Console.WriteLine("La distance restant a parcourir est de {0} mm", this.ValeurCodeurFinal);
     
                            #endregion
                        }
                        else
                        {
                            Console.WriteLine("ValeurcapteurFinal n'a pas la bonne valeur !");
                        }
                        //On recommence dans 500ms.
                        //Thread.Sleep(500); 
                    }
                }
     
            }
     
     
            public void InerrupteurCodeur()     // Méthode arrêt boucle
            {
                _quitter = true;
            }
        }
    --------------------------------------------------------------
    Classe Afficheur.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
     class Afficheur : noeud_can
        {
     
            //Variable témoin du lock.
            private static Object _lock = new Object();
     
            //Variable de contrôle.
            public static bool _quitter = false;
     
            //constructeur par defaut 
            public Afficheur(string nom_peripherique, UInt16 numero_noeud)
                : base(nom_peripherique, numero_noeud)
            {
            }
     
     
            public void CodeurValeurAfficheur(object codeur)
            {
                //Boucle infinie contrôlée.
                while (!_quitter)
                {
                    Console.WriteLine("\n\n\n\tAfficheur");
                    //On verouille l'accès aux variables tant que l'on a pas terminé.
                    lock (_lock)
                    {
                        Codeur grid = (Codeur)codeur;
                        //COB ID
                        uint COB_ID_emission_sdo = (uint)0x600 + numero_noeud; //0x600 trame SDO  cf manuel p668  + numero_noeud (3)
                        if (grid.ValeurCodeurFinal != 0)
                        {
     
                            //Console.WriteLine("debut de l'affichage valeur");
                            if (grid.ValeurCodeurFinal > 255)
                            {
                                //double valeurCodeurAfficheur = (grid.ValeurcodeurFinal * 10.0);
                                double valeurbit = (256 - grid.ValeurCodeurFinal);
                                //int ValeurCodeur = Convert.ToInt32(valeurbit);
                                string Output1 = valeurbit.ToString("X"); //Conversion en châine de caractere
                                byte ValeurInferieurCapteur = Convert.ToByte(Output1, 16); //Conversion en byte pour l'afficheur et hexadécimal
     
                                //Console.WriteLine("\n\tAttendre 100 miliseconde");
                                //Thread.Sleep(200);
                                //test distance
                                //Console.WriteLine("\nenvoi de la trame d'affichage");
                                envoyer_trame(COB_ID_emission_sdo, 8, 0x23, 0x00, 0x52, 0x00, ValeurInferieurCapteur, 0x01, 0x0, 0x0);
                                //Thread.Sleep(200);
     
                            }
                            else
                            {
                                string Output = grid.ValeurCodeurFinal.ToString("X");
     
                                byte ValeurInferieurCodeur = Convert.ToByte(Output, 16);    //Conversion en hexa byte
     
                                //Console.WriteLine("\n\tAttendre 100 miliseconde");
                                //Thread.Sleep(100);
                                //test distance
                                //Console.WriteLine("\nenvoi de la trame d'affichage");
                                envoyer_trame(COB_ID_emission_sdo, 8, 0x23, 0x00, 0x52, 0x00, ValeurInferieurCodeur, 0x0, 0x0, 0x0);
                                //Thread.Sleep(100);
                            }
                        }
                        else
                        {
                            // Si valeur non bonne
                            Console.WriteLine("ValeurcodeurFinal n'a pas la bonne valeur !");
                            envoyer_trame(COB_ID_emission_sdo, 8, 0x23, 0x00, 0x52, 0x00, 0xFF, 0xFF, 0xFF, 0xFF);
                            Thread.Sleep(200);
                        }
                        //On recommence dans 600ms.
                        Thread.Sleep(1000);
                    }
                }
     
            }
     
     
            public void InerrupteurAfficheur()        // Méthode arrêt boucle
            {
                _quitter = true;
            }
     
        }
    -----------------------------------------------------------------
    Classe noeud_can.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
            //Variable témoin du lock.
            private static Object _lock = new Object();
     
        public bool envoyer_trame(uint ID, byte LEN, byte data0, byte data1, byte data2, byte data3, byte data4, byte data5, byte data6, byte data7)
            {
                lock (_lock)
                {
     
                        TPCANStatus gstatus;   // Represents a PCAN status/error code  --  Représente un état / code d'erreur PCAN
                        TPCANMsg message;
                        message.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
                        message.ID = ID;
                        message.LEN = LEN;
                        message.DATA = new byte[8];
                        message.DATA[0] = data0;
                        message.DATA[1] = data1;
                        message.DATA[2] = data2;
                        message.DATA[3] = data3;
                        message.DATA[4] = data4;
                        message.DATA[5] = data5;
                        message.DATA[6] = data6;
                        message.DATA[7] = data7;
                        gstatus = PCANBasic.Write(handle, ref message);
                        if (gstatus != TPCANStatus.PCAN_ERROR_OK)
                            return false;
                        else
                            return true;
                }
            }
     
            /// <summary>
            /// Reception trame variateur
            /// </summary>
            /// <param name="ID"></param>
            /// <param name="LEN"></param>
            /// <returns></returns>
            public TPCANMsg recevoir_trame(uint ID, byte LEN)
            {
                lock (_lock)
                {
                    TPCANStatus gstatus;    // Represents a PCAN status/error code  --  Représente un état / code d'erreur PCAN
                    TPCANMsg message_lu;
                    message_lu.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
                    message_lu.ID = ID;   //0x581
                    message_lu.LEN = LEN;
                    message_lu.DATA = new byte[8];
                    //lire plusieurs trames jusqu'à récupérer la bonne (i.e. avec un COBID de 0x581)
                    while (true)
                    {
                        gstatus = PCANBasic.Read(handle, out message_lu);
                        if (gstatus != TPCANStatus.PCAN_ERROR_OK)
                        {
                            Console.WriteLine("erreur reception trame tension2");
                            System.Environment.Exit(Convert.ToInt32(TPCANStatus.PCAN_ERROR_UNKNOWN));
                        }
                        if (gstatus == TPCANStatus.PCAN_ERROR_OK && message_lu.ID == ID)
                        {
                            //Affiche verification trame retour
                            for (int i = 0; i < 8; i++)
                            {
                                //Console.Write("{0} ", (int)message_lu.DATA[i]);
                                string Tramesréponse = message_lu.DATA[i].ToString("X2");
                                Console.Write("{0} ", Tramesréponse);
                                // test
                                /*
                                Console.Write("COB_ID {0:x} ", message_lu.ID);
                                Console.Write("octet1 {0:x} ", message_lu.DATA[0]);
                                Console.Write("octet2 {0:x} ", message_lu.DATA[1]);
                                Console.Write("octet3 {0:x} ", message_lu.DATA[2]);
                                Console.Write("octet4 {0:x} ", message_lu.DATA[3]);
                                Console.Write("octet5 {0:x} ", message_lu.DATA[4]);
                                Console.Write("octet6 {0:x} ", message_lu.DATA[5]);
                                Console.Write("octet7 {0:x} ", message_lu.DATA[6]);
                                Console.Write("octet8 {0:x} \n", message_lu.DATA[7]);
                                 * */
                            }
                        }
                        return message_lu;
                    }
                }
            }
    -----------------------------------------------------------
    Main
    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
    Console.WriteLine("Lancement boucle");
     
                // Create the thread object, passing in the (CODEUR.codeurvaleur) method
                // via a ThreadStart delegate. This does not start the thread.
                var CodeurBoucle = new Thread(new ParameterizedThreadStart(CODEUR.CodeurValeur));
                //Start the thread
                CodeurBoucle.Start(CAPTEUR);
     
     
                // Create the thread object, passing in the (AFFICHEUR.CodeurValeurAfficheur) method
                // via a ThreadStart delegate. This does not start the thread.
                var AfficheurBoucle = new Thread(new ParameterizedThreadStart(AFFICHEUR.CodeurValeurAfficheur));
                //Start the thread
                AfficheurBoucle.Start(CODEUR);
     
                CodeurBoucle.Join();
                AfficheurBoucle.Join();
                Thread.Sleep(20000);        // Laisse travailler pendant 20 seconde
     
                // Arréter les thread
                CODEUR.InerrupteurCodeur();
                AFFICHEUR.InerrupteurAfficheur();
     
                Console.WriteLine("Thread stoper dans le programme.");
    ---------------------------------------------------------------
    Image console du programme avec la trame vide
    Nom : cmdprogramme.png
Affichages : 123
Taille : 29,7 Ko

    Comme le montre l'image de la console. Dans la zone encadré en orange on voit que je ne reçois pas de trame de réponse du noeud_can avant la phrase "La valeur de intAgain2 = 0". Du coup la méthode de la classe codeur n'a que la valeur du capteur (222), et vu que la valeur de la trame de réponse vaut 0, le nombres de tours et le nombres de centimètres ne peuvent être calculés.

    Le problème vient de mes thread ?
    est-ce que je dois utiliser des sémaphore ou passer par autre chose ?

    S'il faut d'autres informations, indiquer-les moi.

  2. #2
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 183
    Points : 5 754
    Points
    5 754
    Par défaut
    Le code de ta classe noeud_can semble incomplet.

    Tu semble déclarer plusieurs fois la propriété '_lock', il faut que ce soit la même référence d’objet dans tes deux classes pour que le verrouillage 'lock (_lock)' soit effectif.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2014
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    merci de ta réponse, je ferais demain dans ma classe noeud_can la propriété _lock utilisé par les autres classe. Sinon ma classe noeud_can est complet, c'est juste qu'elle utilise une autre classe que je n'ai pas mis car pas utile selon mon point de vue. Je peux toujours la mettre si besoin.

Discussions similaires

  1. [2.0] Valeur vide dans DropDownList
    Par davasm dans le forum ASP.NET
    Réponses: 3
    Dernier message: 23/06/2006, 15h00
  2. [LDAP] Problème lors d'insertion de valeur vide
    Par navis84 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 26/04/2006, 14h26
  3. [Tableaux] Tableau valeur vide pour une clé
    Par hisy dans le forum Langage
    Réponses: 3
    Dernier message: 17/01/2006, 11h49
  4. [Tableaux] Valeur vide Liste Déroulante
    Par ekinoxe dans le forum Langage
    Réponses: 1
    Dernier message: 03/12/2005, 19h47
  5. [CR9] Bug avec les champs à valeur vide ?
    Par Djob dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 15/07/2003, 21h21

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