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

 Delphi Discussion :

Fiche d'attente / Thread ?


Sujet :

Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 39
    Points : 29
    Points
    29
    Par défaut Fiche d'attente / Thread ?
    Bonsoir,

    je souhaite intégrer à mon programme une fenêtre d'attente permettant de faire patienter l'utilisateur pendant des process plus ou moins long (application réseau avec base de données)...

    J'ai bien créé ma fiche avec un timer et un progressbar, lorsque je teste l'affichage de la fiche tout se passe bien mais lorsque j'affiche la fenêtre en phase fonctionnelle si la fenêtre s'affiche, aucune progression n'est visible.

    J'ai lu des infos ici et là sur les threads et je pense que c'est la solution qu'il me faut, cependant je n'arrive pas à comprendre la mise en place de thread.

    Auriez-vous des informations à me communiquer concernant les threads, des codes les concerants, bref les exemples qui me manquent afin que je comprenne...

    Je prends aussi si vous avez une autre solution à me proposer.

    Merci d'avance, Couiss

  2. #2
    Membre averti Avatar de zemeilleurofgreg
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    515
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 515
    Points : 346
    Points
    346
    Par défaut
    Donc si je comprend bien, la fenêtre d'attente s'affiche bien mais aucune progression dans la progressbar ?

    As-tu essayé de mettre un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.ProcessMessage
    avant la modification de la position de la progressBar ?
    [Il était une fois Delphi ....]


  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    Oui, en fait je vais vous mettre le code tel que je l'ai pensé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      if form4.ShowModal=idyes then
      begin
        form2.Label1.Caption:='Traitement en cours...';
        form2.Show;
        application.ProcessMessages;
        {traitement de la tâche}
        form2.Hide;
        application.ProcessMessages;
      end;
    avec form4 une fiche de dialogue et form2 ma fiche d'attente dont le code est :

    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
     
    procedure TForm2.FormShow(Sender: TObject);
    begin
      timer1.Enabled:=true;
    end;
     
    procedure TForm2.Timer1Timer(Sender: TObject);
    begin
      if form2.ProgressBar1.Position>=form2.Progressbar1.Max then form2.Progressbar1.Position:=form2.Progressbar1.Min
      else form2.Progressbar1.Position:=form2.Progressbar1.Position+1;
      application.ProcessMessages;
    end;
     
    procedure TForm2.FormHide(Sender: TObject);
    begin
      label1.Caption:='';
      progressbar1.Position:=0;
      timer1.Enabled:=false;
    end;
    Voilà qui pourra vous aider à comprendre ma manière de faire actuelle.

    Et pendant la tâche à traiter, je n'ai pas la possibilité de mettre des "application.ProcessMessages;" et donc ma fiche d'attente n'est pas réactualisée... c'est pour cela que j'avais pensé aux threads.

    A bientôt, Couiss

  4. #4
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Citation Envoyé par couiss Voir le message
    Et pendant la tâche à traiter, je n'ai pas la possibilité de mettre des "application.ProcessMessages;" et donc ma fiche d'attente n'est pas réactualisée... c'est pour cela que j'avais pensé aux threads.
    Si tu ne peux pas faire de Application.ProcessMessages pendant ton traitement tu ne risques pas d'avoir la moindre progression sur Form2.

    Dans ce cas effectivement, la seule façon d'afficher une progression serait d'utiliser le multi-threading. Je te suggère alors d'effectuer le traitement long dans un thread secondaire.
    De cette façon, tu pourras avoir facilement le thread principal qui traite les messages windows et le thread secondaire qui effectue le traitement long.

    Attention cependant à ce que tu fais dans le traitement long. Si tu travailles avec des objets COM (genre si tu utilises ADO), il ne faudra pas oublier d'appeler CoInitiaize dans le thread secondaire...

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    Oui c'est exactement pour cela que j'en ai besoin...

    Le soucis c'est que je ne comprends pas comment utiliser les threads, j'ai lu la théorie dans la FAQ, j'ai crée mon objet thread mais je ne sais pas quel code mettre (au départ, j'avais pensé mettre le code de la fiche d'attente).

    De plus, je n'ai pas la moindre idée de comment synchroniser le thread et le prog principale, de comment l'appeler, de comment le terminer, ...

    Bref, beaucoup de question qui sont encore flou car je n'ai pas trouvé d'exemple de code qui me serait utile.

    Couiss

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Pour un Thread, il faut juste mettre une boucle dans une surcharge de la méthode Execute
    Pour la File d'Attente, voir la TThreadList !
    Attention, il ne faut pas manipuler une Form depuis un Thread, pas plus qu'utiliser Application.ProcessMessages au risque d'avoir des OS Error 1400 - Handle Invalide !
    Il faut passer par Synchronize dans ce cas, ou différent les traitements par un PostThreadMessage ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    Compris pour les diverses mises en garde...

    En ce qui concerne les threads :

    - doit-on obligatoirement mettre une boucle dans TThread.Execute ?

    - si j'ai bien compris, il vaut mieux execute le code de traitement dans les threads plutôt que les mises à jour de fiche telle pour une fiche d'attente ?

    - peut-on passer des paramètres de ou vers les threads ?

    - peut-on modifier des variables du programme principal via un thread ?

    Voilà pour les premières questions (enfin les premières avec un semblant de compréhension de ma part lol), je vais faire des tests grâce à vos réponses et reviendrai par ici sous peu.

    Merci et à bientôt, Couiss

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par couiss Voir le message
    - doit-on obligatoirement mettre une boucle dans TThread.Execute ?
    Non, tu peux lancer une tache, qui ne doit se faire qu'une seule fois ... par exemple, le download d'un fichier, tu lance juste le Get dans le Execute, et basta ...
    Citation Envoyé par couiss Voir le message
    - si j'ai bien compris, il vaut mieux execute le code de traitement dans les threads plutôt que les mises à jour de fiche telle pour une fiche d'attente ?
    Tout dépend du traitement, l'ergonomie souhaité dans l'application, j'ai bcp de programme où l'utilisateur patiente devant une barre de progression parce que le traitement tourne et dure un peu, et régulièrement cela fait un StepIt
    Citation Envoyé par couiss Voir le message
    - peut-on passer des paramètres de ou vers les threads ?
    ?
    Tu peux passer tes paramètres au Constructeur (une surcharge du Create), tu les stock en propriété privée que le Execute utilisera
    Citation Envoyé par couiss Voir le message
    - peut-on modifier des variables du programme principal via un thread ?
    Oui, tu peux protéger tes modifications par un TCriticalSection ou TMultiReadExclusiveWriteSynchronizer, pour facilité l'écriture, met toutes ces variables dans un objet, avec des propriétés, les Accesseurs Get\Set se chargeant du ThreadSafe ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    Bon alors ça fonctionne très bien lorsque je mets l'action dans le thread, avec le coinitialize et le uncoinitialize, ...

    Mais en fait, l'action actuelle est de créer les répertoires, les fichier de configuration, le fichier ACCESS, l'ensemble des tables et les enregistrements par défaut, ...

    Le fait de mettre l'action dans le thread ne me permets pas de savoir quand la création est terminée et c'est la mon problème car à la suite de cette génération, le programme (la partie utilisateur) démarre !!!

    C'est pourquoi je pense qu'il faudrait que je mette mon attente dans le thread et la génération dans le programme principal ; dites moi si je me trompe dans mon analyse.

    C'est la que je suis bloqué, je ne sais comment faire. Pourriez-vous encore me donner un coup de pouce ?

    Merci d'avance, Couiss

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Je ne comprends pas alors le besoin d'un Thread si l'opération au final est bloquante pour l'utilisateur ...

    Pour ne pas mettre plutôt un SplashScreen (comme Delphi) avec un libellé d'action et\ou une Barre de Progression (comme Delphi 200x), restant afficher tout le temps du démarrage de l'application ... l'utilisateur ira chercher son café pendant ce temps ...

    Si le Thread est obligatoire, tu ajoute une boucle après la création du Thread comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ObjThread := TBiduleThread.Create(Param1, Param2); // Créé en Suspended à False et FreeOnTerminate à False aussi
    try
      Patience.Thread := ObjThread;
      Patience.Show(); // une fenêtre sans bouton fermer pour faire patientez, voire un echange de Message via PostThreadMessage ou Synchronize pour la Progression, ou via un Objet protégé via Section Critique
      while not ObjThread.Terminated do // mettre Terminated à True à la fin du Execute
      begin
        Sleep(1);
        Patience.Refresh(); // une surchage du Refresh va lire l'objet protégé via Section Critique, contenant la Position, le Max de la ProgressBar et\ou un libellé ...
        Application.ProcessMessages();
      end;
    finally
      ObjThread.Free();
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    Salut,

    en fait voici le déroulement que j'avais pensé...

    - splashscreen durant lequel :
    • - création des variables globales ;
    • - des dossiers et fichiers de configuration ;
    • - vérification des licences.

    - affichage de la fiche principale
    • - si fichier de données (BDD) attachée alors démarrage OK ;
    • - sinon :
      • - sélection du dossier de données ou
      • - création des dossiers, fichiers de données ou
      • - restauration (recherche d'une sauvegarde).

    La discussion actuelle porte sur les actions en gras...

    Mes actions sont correctements programmées, ma fiche d'attente aussi mais les actions ne permettent pas une réactualisation correcte de la fiche d'attente et donc l'utilisateur voit une fiche d'attente statique, cela me dérange un peu.

    Mon souhait serait que la fiche d'attente ne soit pas statique mais que l'utilisateur ne puisse continuer tant que l'ensemble des dossiers/fichiers ait été créés.

    Ce n'est peut-être pas les threads qui sont la bonnes méthodes ici, je reste ouvert à d'autres propositions.

    Merci, Couiss

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 39
    Points : 29
    Points
    29
    Par défaut
    Merci beaucoup,

    j'ai appris à utiliser les threads grâce à vos explications et je vous en remercie.

    En espérant que ça aide tout le monde.

    Je tag résolu car mon problème n'en est plus un.

    Couiss

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

Discussions similaires

  1. Relation de Handle d'une fiche avec un Thread
    Par DarkinGoD dans le forum Langage
    Réponses: 1
    Dernier message: 08/03/2008, 18h05
  2. Fenêtre d'attente + thread = problème :(
    Par brupistone dans le forum EDT/SwingWorker
    Réponses: 2
    Dernier message: 05/04/2007, 12h35
  3. [MFC] Creation d'un thread pour un popup d'attente
    Par firejocker dans le forum MFC
    Réponses: 8
    Dernier message: 07/02/2006, 09h15
  4. Afficher une fiche dans un thread
    Par abatonime dans le forum Langage
    Réponses: 5
    Dernier message: 05/11/2005, 22h26
  5. fenêtre d'attente dans un thread
    Par KRis dans le forum Langage
    Réponses: 3
    Dernier message: 25/08/2005, 10h29

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