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

Threads & Processus C++ Discussion :

ProgressBar sur une TForm lié à un traitement base de données


Sujet :

Threads & Processus C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 40
    Points : 38
    Points
    38
    Par défaut ProgressBar sur une TForm lié à un traitement base de données
    Une procédure incluse dans une DLL doit intégrer 8 fichiers CSV (de manière contrôlée) en base de données (BDE).
    Pour que l'utilisateur ne pense pas que l'appli est plantée, je me dois de lui indiquer la progression (nombre de fichiers, nombre d'octets par fichier).

    Inutile de vous dire que toutes les dispositions pour faire progresser les deux barres sont vaines, le processus est ancré dans sa procédure de mise à jour ne laisse plus Windows gérer ses messages.

    J'ai fait une recherche sur les forums, il semble que ce soit le problème de personne : j'ai donc pensé à créer un thread pour accomplir la tâche.

    J'utilise C++BUILDER V5 sur un PC 4 coeurs
    Là ca se complique : qui dit base de données dit création d'une session propre au thread (le Sessions->OpenSession("sessionthread") achevé sans erreur me retourne un 'Base de données inconnue' dès la première requête (Bdd de l'appli principale + session nouvellement créée). Je n'ai pas trouvé le moyen d'associer la nouvelle session à la Bdd principale.
    Plusieurs données créées dans le thread principal (tableau de String + tableau de int ) doivent être utilisées dans le thread créé.
    J'ai donc réalisé un lien entre la form principale et le thread par les headers, tout se passe correctement.
    La form est créée (je suis en DLL) par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    TForm1 *form = new TForm1(this):
    form->ShowModal();
    delete form; // et là c'est la bérézina : manifestement un débordement de pile qui plante l'appli.
    Quelqu'un aurait un tutoriel ou une doc COMPLETE sur l'utilisation de thread c++Builder utilisant une base de données + passage de paramètres (les tuto Sort, multi Sort etc...ne me sont d'aucune utilité)
    Merci d'avance au MasterThread qui me répondra

  2. #2
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2009
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Juillet 2009
    Messages : 114
    Points : 73
    Points
    73
    Par défaut
    on ne delet pas une Form ...

    On utilise close() . Normalement cette fonction fera le boulot de delete pour toi ...



    Citation Envoyé par phpdev Voir le message
    Une procédure incluse dans une DLL doit intégrer 8 fichiers CSV (de manière contrôlée) en base de données (BDE).
    Pour que l'utilisateur ne pense pas que l'appli est plantée, je me dois de lui indiquer la progression (nombre de fichiers, nombre d'octets par fichier).

    Inutile de vous dire que toutes les dispositions pour faire progresser les deux barres sont vaines, le processus est ancré dans sa procédure de mise à jour ne laisse plus Windows gérer ses messages.

    J'ai fait une recherche sur les forums, il semble que ce soit le problème de personne : j'ai donc pensé à créer un thread pour accomplir la tâche.

    J'utilise C++BUILDER V5 sur un PC 4 coeurs
    Là ca se complique : qui dit base de données dit création d'une session propre au thread (le Sessions->OpenSession("sessionthread") achevé sans erreur me retourne un 'Base de données inconnue' dès la première requête (Bdd de l'appli principale + session nouvellement créée). Je n'ai pas trouvé le moyen d'associer la nouvelle session à la Bdd principale.
    Plusieurs données créées dans le thread principal (tableau de String + tableau de int ) doivent être utilisées dans le thread créé.
    J'ai donc réalisé un lien entre la form principale et le thread par les headers, tout se passe correctement.
    La form est créée (je suis en DLL) par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    TForm1 *form = new TForm1(this):
    form->ShowModal();
    delete form; // et là c'est la bérézina : manifestement un débordement de pile qui plante l'appli.
    Quelqu'un aurait un tutoriel ou une doc COMPLETE sur l'utilisation de thread c++Builder utilisant une base de données + passage de paramètres (les tuto Sort, multi Sort etc...ne me sont d'aucune utilité)
    Merci d'avance au MasterThread qui me répondra

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Il faudrait plus de détail sur le passage de paramètres. Mais moi, je fais comme cela.
    Et aussi faire attention que ta base ne soit pas lockée sur le thread de création

    J'ai une classe mère IThread (<- original non? ) dont tous mes threads dérivent:

    IThread.h:
    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
    #ifndef IThreadH
    #define IThreadH
     
    #include<Classes.hpp>
    #include<SyncObjs.hpp>
     
     
    class IThread : public Classes::TThread {
    // Constructor & Destructor
    public:
     
        __fastcall IThread(bool /*create_suspended*/);
     
        __fastcall ~IThread() { delete_lock(); }
     
     
    protected:
     
        void delete_lock() {
            if (lock != NULL) {
                delete lock;
                lock = NULL;
            }
        }
     
     
    // Public Interface
    public:
     
        void __fastcall Execute() {}
     
        bool set_get_is_finished(bool /*set_mode*/, bool /*is_finished*/ = false);
     
     
    // Attributes
    protected:
     
        Syncobjs::TCriticalSection* lock;
     
        bool is_finished;
    };
     
     
    #endif // IThreadH

    IThread.cpp:
    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
    #pragma hdrstop
     
    #include "IThread.h"
     
    #include<vcl.h>
     
     
    using Classes::TThread;
    using Syncobjs::TCriticalSection;
     
     
    // Constructor
     
    __fastcall IThread::IThread(bool create_suspended) : IThread(create_suspended), lock(new TCriticalSection()), is_finished(false) {}
     
     
    // Public Interface
     
    bool IThread::set_get_is_finished(bool set_mode, bool new_is_finished) {
        bool ret;
     
        lock->Acquire();
     
        if (set_mode) {
            is_finished = new_is_finished;
        }
     
        ret = is_finished;
     
        lock->Release();
     
        return ret;
    }

    Ensuite, tu dérives en y mettant tous les attributs et getters qu'il faut pour configurer ton thread avant le Start (et en copiant/ collant le destructeur pour détruire le lock ).

    Comme j'ai refait le système de lock parce que j'ai eu des problèmes avec le TThread.WaitFor qui n'attendait pas (pourquoi???? Est-ce moi qui avait mal fait un truc ??? ), la méthode doit ressembler à cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void __fastcall My_Thread::Execute() {
        (void) set_get_is_finished(true, false);
     
    //  ... Ton code ici
    //  ...
    //  ... Pour savoir si ton thread a été arrêté: bool tmp_is_finished = set_get_is_finished(false);
    //  ...
     
    //  The method Synchronize executes one method on the main thread: UI update for example
    //  ...
     
        (void) set_get_is_finished(true, true);
    }
    Et enfin, j'ai des macros pour lancer, supprimer et attendre un 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
    36
    37
    38
    39
    40
    #define KILL_THREAD \
        if (thread != NULL) { \
            (void) thread->set_get_is_finished(true, true); \
        }
     
     
    #define KILL_DELETE_THREAD \
        if (thread != NULL) { \
            (void) thread->set_get_is_finished(true, true); \
             \
            while( !thread->set_get_is_finished(false) ) { \
                Sleep(100); \
            } \
             \
            delete thread; \
            thread = NULL; \
        }
     
    #define LAUNCH_THREAD \
        WAIT_DELETE_THREAD \
         \
        thread = new Thread_Client(true); \
         \
        if (thread != NULL) { \
            /* thread->XXX to configure the new thread */ \
             \
            thread->Start(); \
             \
            /* ... */ \
        }
     
    #define WAIT_DELETE_THREAD \
        if (thread != NULL) { \
            while( !thread->set_get_is_finished(false) ) { \
                Sleep(100); \
            } \
             \
            delete thread; \
            thread = NULL; \
        }

Discussions similaires

  1. Affichage d'un ProgressBar sur une form splash
    Par colorid dans le forum Langage
    Réponses: 3
    Dernier message: 12/10/2012, 16h43
  2. Réponses: 0
    Dernier message: 01/08/2012, 11h02
  3. Réponses: 2
    Dernier message: 20/01/2012, 16h02
  4. [XL-2007] Remplissage conditionnel d'une combobox sur une partie seulement de la base
    Par csempere dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 17/06/2010, 14h52
  5. Réponses: 1
    Dernier message: 21/07/2009, 11h51

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