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++Builder Discussion :

Comment accéder aux objets VCL à partir d'un thread tiers


Sujet :

C++Builder

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 61
    Points : 48
    Points
    48
    Par défaut Comment accéder aux objets VCL à partir d'un thread tiers
    Bonjour,
    J'utilise une API CanOpen fournie dans une librairie.
    Cette API me fournit une callback à chaque fois qu'un PDO est transmis ; cette callback est donc exécutée dans le contexte du thread de cette API.

    Comment, à lartir de cette callback, puis-je accéder sans risque aux objets VCL mour mettre à jour mon IHM.

    Merci d'avance pour un petit exemple succinct.

  2. #2
    Membre régulier
    Inscrit en
    Août 2005
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 136
    Points : 115
    Points
    115
    Par défaut
    Bonjour,

    tu utilise quelle Borland?

    dans BDS 6, quand tu crée une thread a partir d'un composant TThread, celui ci te donne un exemple pour accéder au composant.
    il faut utiliser une méthode "synchronize" ou quelque chose comme ça.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 61
    Points : 48
    Points
    48
    Par défaut
    J'utilise BCB6.
    Je n'utilise pas d'objet TThread. La librairie CanOpen est déjà exécutée dans un thread. Je n'ai donc pas la méthode Synchronize à disposition.
    Je pense qu'il faut utiliser des choses genre "section critique" mais j'avoue que je ne sais pas trop coment m'y prendre...

  4. #4
    Membre régulier
    Inscrit en
    Août 2005
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 136
    Points : 115
    Points
    115
    Par défaut
    les sections critiques sont la pour éviter le multi-accès à la même zone mémoire.

    si tu a un timer sur ta form qui met à jour les données, tu peux utiliser ce genre de chose.

    sinon, dans un cas similaire, je m'étais tapé une thread suplémentaire, qui s'occupait de mettre à jour les données, tout ça géré par un événement ( avec une section critique, ça peut être mieux! ) déclenché par la fonction de callback quand elle avait fini son traitement.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 61
    Points : 48
    Points
    48
    Par défaut
    Effectivement, je pourrais utiliser la démarche suivante :

    1) La callback de l'aPI CanOpen (dans le contexte de son thread) met à jour les données en encadrant l'opération par TCriticalSection::Acquire et TCriticalSection::Release puis envoie un signal à la fenêtre de l'IHM.

    2) l'IHM se met alors à jour en lisant ces mêmes données également via TCriticalSetion.

    Toutefois cela me paraît un peu lourd.

    N'y a t-il pas moyen, à partir de la callcack, d'attendre le thread principal pour mettre à jour les objets VCL en dehors de la méthode Synchronize ?

    De plus, lors de la réception de la callback, plusieurs messages peuvent être présents dans une queue. Cette queue doit être lue dans une boucle jusqu'à ce qu'elle soit vide. il serait donc préférable que la mise à jour de l'IHM soit synchronisée avec cette lecture.

    Dans l'esprit, un truc du genre :

    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
     
    // Dans la callback appelée par le thread de l'API
    TCan::callback
    {
       do
       {
          m_variable = queue.message;
          MyForm->majIhm(m_variable); // Pour ça, il faudrait sécuriser l'accès aux objets VCL
     
       } while(queue == vide);
    }
     
    TMyForm::majIhm(AnsiString Valeur)
    {
       MyLabel->Caption = Valeur;
    }

  6. #6
    Membre régulier
    Inscrit en
    Août 2005
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 136
    Points : 115
    Points
    115
    Par défaut
    en fait, je me demande si c'est une bonne idée de vouloir afficher les données depuis la fonction de callback.

    en effet, cette fonction doit être le plus rapide possible. malheureusement, la synchronisation entre la callback et l'affichage risque d'être lente. les temps d'affichages aussi d'ailleurs...

    sinon, j'ai cru comprendre dans l'aide de borland, que tu peut faire toi même ta fonction synchronize, a l'aide des sections critiques.

    Remarque:
    Comme Synchronize utilise la boucle des messages, elle ne fonctionne pas dans les applications console. Vous devez utiliser d'autres mécanismes, comme les sections critiques, pour protéger l'accès aux objets VCL dans les applications consoles.
    perso, j'aurais séparé la récupération des données, et l'affichage. d'expérience, c'est beaucoup plus sur, même si c'est plus lourd a coder.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 61
    Points : 48
    Points
    48
    Par défaut
    Merci pour tous ces conseils zenetcalme.

    Finalement j'ai opté pour un PostMessage() vers la fenêtre principale pour mettre à jour l'IHM à chaque fois qu'un message est lu dans la callback. Le thread CanOpen et l'appli principale utilisant un TCriticalSection pour accéder aux données échangées.

    Toutefois je pense que je vais plutôt utiliser le TThreadList pour lesdonnées échangées. Cela évitera l'utilisation de la section critique et de plus, comme les 2 threads travaillent de manière asynchrone, cela assurera qu'aucune information n'est oubliée par le lecteur.

  8. #8
    Membre régulier
    Inscrit en
    Août 2005
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 136
    Points : 115
    Points
    115
    Par défaut
    Pas bête pour le postmessage!

    heureux d'avoir pu t'aider...

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

Discussions similaires

  1. comment accéder aux objets éléments d'une cbo?
    Par Philippe PONS dans le forum Windows Forms
    Réponses: 2
    Dernier message: 22/05/2009, 16h19
  2. comment accéder aux ressources locales à partir d'une appli web
    Par lginoux dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 01/04/2009, 10h46
  3. Réponses: 0
    Dernier message: 03/05/2008, 15h13
  4. Réponses: 2
    Dernier message: 13/02/2008, 10h58
  5. Comment accèder aux composants graphique à partir d'un autre thread ?
    Par PerpetualSnow dans le forum Windows Forms
    Réponses: 6
    Dernier message: 07/03/2007, 11h11

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