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 :

attendre le retour d une fonction avant d en lancer une autre dans une boucle, enfin quelque chose du genre


Sujet :

Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2012
    Messages : 26
    Points : 20
    Points
    20
    Par défaut attendre le retour d une fonction avant d en lancer une autre dans une boucle, enfin quelque chose du genre
    Bonjour

    Je parcours un fichier dont j extrait differente valeur à l aide d un reapeat until EOF(F);
    Dans cette boucle j apelle une fonction qui effectue differents calculs et ecrit dans un fichier de sortie ce resultat à l aide d'un Writeln(G,ma valeur extraite de ma fonction)
    toutes ces opérations se font dans 3 boucles imbriquées.
    Le tout fonctionne parfaitement mais parfois, ça plante.
    Resultat, ça ne m ecrit que partiellement dans le fichier puis 'erreur....'
    j'essaie, re-essaye et là ça fonctionne.

    J en ai deduit que celapouvait provenir du fait que un nouvel appel à la fonction s effectuait alors même que la ligne n avait pas encore été ecrite dans le fichier de sortie mais peut etre n est-ce pas cela...

    toujours est il que si mon hypothese est exacte, il me suffirait, de m'assurer que la ligne soit bien ecrite dans le fichier pour lancer l 'appel à la fonction mais comment faire etant donné que writeln est une procedure ?
    Un while peut etre mais là je ne vois pas comment le mettre en place etant donné que l appel à la fonction se fait avant l ecriture dans le fichier ...

    Je suis ouvert à toutes propositions....

    merci pour votre aide

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    en dehors d'un contexte multithread, il ne peut y avoir un double appel.

    qu'est-ce qui te fait penser qu'il y a un nouvel appel de la fonction ?
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2012
    Messages : 26
    Points : 20
    Points
    20
    Par défaut
    En fait la ligne d appel est en surbrillance et la ligne sauvegardee à l issue de l appel n est pas complete donc je me dis que la fonction a retourné la valeur correctement mais que la sauvegarde n a pas été terminé parce qu une nouvelle valeur est arrivée et que du coup il ne sait plus quoi sauvegarder...

    Mais mon raisonnement tient il au moins la route ?

  4. #4
    Membre confirmé

    Homme Profil pro
    Chef de Projet ATIC
    Inscrit en
    Novembre 2005
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Chef de Projet ATIC
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2005
    Messages : 274
    Points : 508
    Points
    508
    Par défaut
    Comme l'indique Paul, il n'y a pas de risque d'avoir 2 writeln en même temps si tu n'utilises pas les threads (ou des timers).

    Ce qui peut se passer, éventuellement, c'est une violation d'accès au fichier s'il est verrouillé.

    Ton fichier de sortie, est-il ouvert une fois au début et refermé tout à la fin, ou bien tu l'ouvres/fermes à chaque appel ?

    Quel est l'erreur retournée au moment du plantage ?

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2012
    Messages : 26
    Points : 20
    Points
    20
    Par défaut
    effectivement le fichier est ouvert au debut puis refermé à la fin

    Le message d erreur est erreur EAccessViolation

    et quand j arrete, ça se repositionne sur l appel de la fonction

    merci

    Voici le code simplifié :
    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
    for Fl := 0 to FileListBox1.Count - 1 do
    begin
      for BK := 0 to length(Brique) - 1 do
      begin
        for T := strtoint(ed_T_debut.Text) to strtoint(ed_T_fin.Text) do
        begin
          AssignFile(F, FileListBox1.Items[Fl]);
          Reset(F);
          AssignFile(G, Dir);
          Rewrite(G);
          repeat
            Readln(F, stg);
            B := AppleALAFonction(stg);
            Writeln(G, Dte + ';' + floattostr(cours) + ';' + inttostr(ind)
                + ';' + inttostr(B));
          until EOF(F);
          CloseFile(G);
          CloseFile(F);
        end;
        // ---fin T
      end; // ---fin BK
    end;

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    hum...tu peux ajouter un Flush(G) après le WriteLn(G,...) pour vider les buffers d'écritures, mais n'aurais-tu pas une erreur dans AppleALAFonction ?

    (désolé pour l'indentation)
    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
     
          AssignFile(F, FileListBox1.Items[Fl]);
          Reset(F);
     try
          AssignFile(G, Dir);
          Rewrite(G);
      try
          repeat
            Readln(F, stg);
         try
            B := AppleALAFonction(stg);
            Writeln(G, Dte, ';', cours, ';', ind, ';', B);
          except
            on e : Exception do
             ShowMessage(e.Message);
          end;
          until EOF(F);
       finally
          CloseFile(G);
       end;
     finally
          CloseFile(F);
     end;
    note que la fonction WriteLn peut gérer différents paramètres de différents types...tu peux même spécifier un format numérique : WriteLn(G, cours:0:2);.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2012
    Messages : 26
    Points : 20
    Points
    20
    Par défaut
    Merci pour ta réponse.
    Le message d erreur qui s affiche est le suivant :

    violation d acces 00403123 à l adresse dans le module 'mon.exe'.
    Lecture de l adresse 3ff00000
    .

    Perso,je ne sais pas ce que cela signifie mais si c est dans ma fonction, n y aurait il pas un moyen de mettre un point d arret là ou l erreur apparait plustot qu au retour ?

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    dans le menu Chercher tu peux tenter de localiser l'erreur (Erreur d'exécution...) à l'adresse $00403123.

    mais ça ne fonctionne que si l'erreur est dans l'exécutable (et non dans une DLL qu'il utilise).

    Sinon le mode pas à pas te permet de suivre l'évolution de ton programme.

    J'utilise aussi une technique fort simple et très pratique, tu ajoutes un AllocConsole() en début de boucle pour ouvrir une console texte, et tu places des WriteLn(...) aux endroits stratégiques pour savoir où en est ton programme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    begin
    {$DEFINE LOG} // ou pas
    {$IFDEF LOG}AllocConsole;{$ENDIF}
      while not eof(f) do
      begin
        {$IFDEF LOG}WriteLn('lecture d''une ligne');{$ENDIF}
        ReadLn(f, s);
        {$IFDEF LOG}WriteLn('traitement de ', s);{$ENDIF}
        Traitement(s);
        {$IFDEF LOG}WriteLn('on boucle....');{$ENDIF}
      end;
    end;
    le $IFDEF est là pour désactiver tout au besoin.

    tu peux aussi évidemment mettre des conditions sur tes WriteLn pour limiter l'affichage


    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
     
    {$DEFINE LOG} // ou pas
    {$IFDEF LOG}
    var
      Line: Integer;
    {$ENDIF}
    begin
    {$IFDEF LOG}
      AllocConsole; 
      Line := 0;
    {$ENDIF}
      while not eof(f) do
      begin
        ReadLn(f, s);
        {$IFDEF LOG}
        Inc(Line); 
        if Line > 100 then  // on sait que les 100 premières lignes ne pose pas de problème
          WriteLn('traitement de ', s);
        {$ENDIF}
        Traitement(s);
      end;
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2012
    Messages : 26
    Points : 20
    Points
    20
    Par défaut
    Merci.

    J ai repris mon code et ai determiné où se produisait l erreur.
    il s agit en fait d une boucle . Parfois cela passait , parfois non, je ne me l explique pas...

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

Discussions similaires

  1. [Débutant] Attendre la fin d'un Shell avant d'en lancer un autre
    Par tardmonkey dans le forum VB.NET
    Réponses: 2
    Dernier message: 08/01/2013, 16h17
  2. Réponses: 7
    Dernier message: 07/07/2010, 12h17
  3. Réponses: 1
    Dernier message: 14/10/2009, 15h07
  4. Réponses: 2
    Dernier message: 03/09/2009, 17h43
  5. Réponses: 1
    Dernier message: 31/08/2009, 22h48

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