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 :

PB de recuperation de données en asynchrone !!


Sujet :

C++

  1. #1
    Membre averti Avatar de Stopher
    Homme Profil pro
    Responsable technique
    Inscrit en
    Juin 2004
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 198
    Points : 446
    Points
    446
    Par défaut PB de recuperation de données en asynchrone !!
    Salut ,
    voila mon soucis , je gere un programme qui recupere des codes barres via le port serie , le principe est le suivant :
    le main lance un thread lecture qui est bloqué , dans l'attente d'un evenement sur le handle du port serie !
    puis recupere les données et les affiches ... voila le code de ce thread :

    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
     
    void __fastcall serie::Execute()
    {
    nbr_octet_a_lire = 1;
    char c;
    terminer = false;
    while (!terminer)
    {
    if (!ReadFile(Form1->hCom,&Buffer_lecture,nbr_octet_a_lire,&nbr_octet_lu,&Form1->ovl_lecture))
             {
             WaitForSingleObject(Form1->ovl_lecture.hEvent,INFINITE);
     
             if(GetLastError() == ERROR_IO_PENDING) //lecture mise en attente pas l'os
              {
                if (GetOverlappedResult(Form1->hCom,&Form1->ovl_lecture,&nbr_octet_lu,FALSE))
                 {
                 if (nbr_octet_lu!=0)
                    {
                    Synchronize(lecture_buffer);
                    }
                 }
               }
             }
             else
             {
             ShowMessage("erreur_lecture port");
             }
    } //Fin du While
     
    }
    //---------------------------------------------------------------------------
    void __fastcall serie::lecture_buffer()
    {
    Form1->Memo1->Text=Form1->Memo1->Text + Buffer_lecture;
    }
    le probleme est le suivant :
    je dois initialiser le nombre d'octet à lire pour le readfile() , seulement les codes barres recuperé sont de 2 sortes l'un composé de 8octets , l'autre de 6 ... lorsque j'initialise nbr_octet_a_lire à 8 , tout les codes barres composés de 8 octets , passes sans probleme , mais si je passe un code barre de 6octets , rien ne se passe , il faut que je passe une seconde fois le code barre pour qu'il y ai 8 octets .... comment faire pour ne pas avoir à choisir le nombre d'octet à lire ?ou alors ne pas attendre que le buffer ateigne la valeur entrée pour le recuperer ??

    Je ne sais pas si j'ai était assez clair , mais mon probleme n'est pas evident à expliquer !
    Merci d'avance pour vos posts !

  2. #2
    Membre actif Avatar de Grulim
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 234
    Points : 288
    Points
    288
    Par défaut
    2 questions:
    Pourquoi lis-tu en asynchrone ?
    Utilises-tu la fonction SetCommTimeouts (si oui, montre ces parametres) ?

  3. #3
    Membre averti Avatar de Stopher
    Homme Profil pro
    Responsable technique
    Inscrit en
    Juin 2004
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 198
    Points : 446
    Points
    446
    Par défaut pk je li en asynchrone
    je li en asynchrone , pour la simple et bonne raison que ca m'est imposé ... j'ai deja fait le programme en synchrone , qui fonctionnait tres bien , seulement mon chef de projet voulait que ce soit un thread qui gere separement la lecture avec gestion d'evenement .... voila .

    oui j'utilise des SetComTimeouts , voila les parametres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    COMMTIMEOUTS comout = {0}; // pas de timeout
     
    .....
     
    SetCommTimeouts(hCom,&comout);
    y aurait il une erreur la dedans ?

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 754
    Points : 10 719
    Points
    10 719
    Billets dans le blog
    3
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (!ReadFile(Form1->hCom,&Buffer_lecture,nbr_octet_a_lire,&nbr_octet_lu,&Form1->ovl_lecture)) 
             { 
             WaitForSingleObject(Form1->ovl_lecture.hEvent,INFINITE);
    Moui, mais utilisé comme àa ça revient à faire du synchrone avec de l'asynchrone. Il faudrait tester la valeur de retour de WaitForSingleObject au passage aussi.
    Pas besoin d'être asynchrone si t'as un thread à part. Un simple ReadFile bloquant simplifie ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    if (!ReadFile(Form1->hCom,&Buffer_lecture,nbr_octet_a_lire,&nbr_octet_lu,NULL)) 
    { 
        if (nbr_octet_lu!=0) 
        { 
            Synchronize(lecture_buffer); 
        } // et sinon ?
    } 
    else 
    { 
        ShowMessage("erreur_lecture port"); 
    }

  5. #5
    Membre averti Avatar de Stopher
    Homme Profil pro
    Responsable technique
    Inscrit en
    Juin 2004
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 198
    Points : 446
    Points
    446
    Par défaut ok
    d'acord ,tout d'abord , merci pour vos posts ,
    Mais si je n'utilise pas WaitForSingleObject() , la boucle infinie du thread tournerat sans arret , à l'attente d'un evenement sur le port , je pense donc qu'il est preferable de garder cette fonction . Je vais rajouter le test de la valeure de retour de WaitForSingleObject( ) ...
    Mais au niveau du nombre d'octets à lire .... faut il mettre 1 pour qu'il les lises 1par 1 ou directement 8 ? afin que les codes B de 8 ou 8 octets puissent etre lue ! :

  6. #6
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 754
    Points : 10 719
    Points
    10 719
    Billets dans le blog
    3
    Par défaut
    ReadIntervalTimeout
    Maximum time allowed to elapse between the arrival of two bytes on the communications line, in milliseconds. During a ReadFile operation, the time period begins when the first byte is received. If the interval between the arrival of any two bytes exceeds this amount, the ReadFile operation is completed and any buffered data is returned. A value of zero indicates that interval time-outs are not used.
    Spécifie une valeur de timeout correcte et t'auras plus de problème, tu pourras mettre 1024 et ça marchera.

    Mais si je n'utilise pas WaitForSingleObject() , la boucle infinie du thread tournerat sans arret , à l'attente d'un evenement sur le port , je pense donc qu'il est preferable de garder cette fonction . Je vais rajouter le test de la valeure de retour de WaitForSingleObject( ) ...
    Sauf que dans ton exemple tu utilises INFINITE. Mais même, WaitCommEvent remplit à peu près la même fonctionnalité.

    Un peu de lecture:
    http://msdn.microsoft.com/library/en-us/dnfiles/html/msdn_serial.asp
    http://c.developpez.com/faq/vc/?page...WithSerialPort

  7. #7
    Membre averti Avatar de Stopher
    Homme Profil pro
    Responsable technique
    Inscrit en
    Juin 2004
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 198
    Points : 446
    Points
    446
    Par défaut Resolu
    Probleme resolu , un grand merci à tous !
    8)

  8. #8
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 754
    Points : 10 719
    Points
    10 719
    Billets dans le blog
    3
    Par défaut
    C'était quoi alors ?

  9. #9
    Membre averti Avatar de Stopher
    Homme Profil pro
    Responsable technique
    Inscrit en
    Juin 2004
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 198
    Points : 446
    Points
    446
    Par défaut voila laresolution ...
    je ne sais pas si c'est la solution ideale , mais dans tous les cas j'ai pu la tester avec une bonne 50ene de codes barres , et aucun bug n'est survenu , aucun ralentissement meme avec plussieur saisies par seconde tous fonctionnai vraiment bien ! !
    voila le code utilisé :
    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
     
    void __fastcall serie::Execute()
    {
    nbr_octet_a_lire = 1;
    char c;
    terminer = false;
    while (!terminer)
    {
    if (!ReadFile(Form1->hCom,&Buffer_lecture,nbr_octet_a_lire,&nbr_octet_lu,&Form1->ovl_lecture))
             {
             WaitForSingleObject(Form1->ovl_lecture.hEvent,INFINITE);
     
             if(GetLastError() == ERROR_IO_PENDING) //lecture mise en attente pas l'os
              {
                if (GetOverlappedResult(Form1->hCom,&Form1->ovl_lecture,&nbr_octet_lu,FALSE))
                 {
                 if (nbr_octet_lu!=0)
                    {
                    Synchronize(lecture_buffer);
                    }
                 }
               }
             }
             else
             {
              if (GetOverlappedResult(Form1->hCom,&Form1->ovl_lecture,&nbr_octet_lu,FALSE))
                 {
                 if (nbr_octet_lu!=0)
                    {
                    Synchronize(lecture_buffer);
                    }
                 }
             }
    } //Fin du While
    je fait un test du readfile qui me renvoie 1 ou 0 or dans mon ancien code , je ne traite qu'un seul de ces cas! la solution est la , j'ai remarqué , que lorsque je passé un code barre , le if (!read ...... etait validé une seul fois , puis ceului ci renvoyait sa valeur inverse (1) autant de foi qu'il restait de caracteres à lire , j'ai donc exploité ma decouverte en ajoutant un "else" apres le "if (!readfile ....." et à l'interieur de ce "else" j'effectue une lecture sur le buffer .... et la champagne , je m'apercoit que cela fonctionne tres bien meme apres des tests de torture pour trouver un bug , tout allé pour le mieux !!!!!
    le code posté n'est pas tout à fait ceului utilisé actuellement , ayant oublié de sauvegarder mes données sur ma clée usb .... mais ca y ressemble fortement !!!

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

Discussions similaires

  1. [VB.NET] Recuperer des données ds un fichier
    Par Aspic dans le forum VB.NET
    Réponses: 2
    Dernier message: 03/11/2005, 10h31
  2. [vbexcel]recuperation de données
    Par Mugette dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 13/10/2005, 14h01
  3. Mysql LongBlob: recuperer les données
    Par froz dans le forum SGBD
    Réponses: 1
    Dernier message: 24/08/2005, 15h41
  4. Recuperer des données d'access
    Par Lucier dans le forum MFC
    Réponses: 18
    Dernier message: 25/11/2004, 11h29
  5. Réponses: 3
    Dernier message: 22/02/2004, 21h09

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