Probleme de lecture de fichier avec threads

Clercq Messages postés 19 Date d'inscription samedi 18 décembre 2004 Statut Membre Dernière intervention 14 juin 2006 - 9 juin 2006 à 17:14
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 - 21 juin 2006 à 23:02
Bonjour,

Dans la famille probleme de debutant je demande le graphique...

Voili voilou, pour faire mon graphique je lis dans un fichier les valeurs à afficher dans le graphe. Mais aussi incroyable que cela puisse etre, à partir d'une certaine valeur constante le programme plante .... alors qu'avec des valeur = ou > dans le meme fichier (valeur donc variable :p) ça marche .... vous pouvez me dire pourquoi ?

ça marche :

15:48:40
3600
15:48:40
3600
15:48:41
3600
15:48:41
3600
15:48:42
3600
15:48:42
3600
15:48:43
3600
15:48:43
3600
15:48:44
3600
15:48:44
3600

ça marche pu :

15:48:40
4909
15:48:40
4909
15:48:41
4909
15:48:41
4909
15:48:42
4909
15:48:42
4909
15:48:43
4909
15:48:43
4909
15:48:44
4909
15:48:44
4909

ça remarche !!! :

15:48:40
5410
15:48:40
5210
15:48:41
5200
15:48:41
4120
15:48:42
6520
15:48:42
4200
15:48:43
4510
15:48:43
7300
15:48:44
4990
15:48:44
5001

et voici mon code qui utilise le graphe :

unit Graphe;


interface


uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  TeEngine, Series, Menus, ExtCtrls, TeeProcs, Chart, StdCtrls;


type
  TForm3 = class(TForm)
    Chart1: TChart;
    MainMenu1: TMainMenu;
    Fichier1: TMenuItem;
    Quitter1: TMenuItem;
    Series1: TLineSeries;
    Series2: TLineSeries;
    OpenDialog1: TOpenDialog;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    ButtonExit: TButton;
    procedure Quitter1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ShowAsStartupScreen;
    procedure CheckBox1Click(Sender: TObject);
    procedure CheckBox2Click(Sender: TObject);
    procedure ButtonExitClick(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;


var
  Form3: TForm3;


implementation


{$R *.DFM}


procedure TForm3.Quitter1Click(Sender: TObject);
begin
     close;
end;


procedure TForm3.FormCreate(Sender: TObject);
begin
     Series1.Clear;
     Series2.Clear;
//     Ligne1.Checked := True;
end;


procedure TForm3.ShowAsStartupScreen;
begin
//  BorderIcons := [];
//  caption := '';
//  BorderStyle := bsDialog;
//  Ok.Visible := false;
  Show;
end;


procedure TForm3.CheckBox1Click(Sender: TObject);
var
   Fichier  : TextFile;
   bufVal   : string;
   bufHeure : string;
   oDial    : boolean;
begin
     if CheckBox1.Checked = True then
     begin
          OpenDialog1.initialDir := '.\save';
          oDial := OpenDialog1.Execute;
          if not (OpenDialog1.FileName = '') then
          begin
               AssignFile(Fichier, OpenDialog1.FileName);
               Reset(Fichier); // Ouverture en mode lecture
               With Chart1 do
               begin
                    while not Eof(Fichier) do
                    begin
                         Readln(Fichier,bufHeure);
                         Readln(Fichier, bufVal);
                         Series1.Add(StrToInt(bufVal),bufHeure);
                    end;
               end;
               Series1.Active := True;
          end;
          if (OpenDialog1.FileName = '') or not oDial then
          begin
//             ShowMessage('Veuillez ouvrir un fichier');
               CheckBox1.Checked := False;
          end;
     end;
     if CheckBox1.Checked = False then
     begin
        Series1.Clear;
        Series1.Active := False;
     end;
end;


procedure TForm3.CheckBox2Click(Sender: TObject);
var
   Fichier : TextFile;
   bufVal   : string;
   bufHeure : string;
   oDial : boolean;
begin
     if CheckBox2.Checked = True then
     begin
          OpenDialog1.initialDir := '.\save';
          oDial := OpenDialog1.Execute;
          if not (OpenDialog1.FileName = '') then
          begin
               AssignFile(Fichier, OpenDialog1.FileName);
               Reset(Fichier); // Ouverture en mode lecture
               With Chart1 do
               begin
                    while not Eof(Fichier) do
                    begin
                         Readln(Fichier,bufHeure);
                         Readln(Fichier, bufVal);
                         Series2.Add(StrToInt(bufVal),bufHeure);
                    end;
               end;
               Series2.Active := True;
          end;
          if (OpenDialog1.FileName = '') or not oDial then
          begin
               CheckBox2.Checked := False;
          end;
     end;
     if CheckBox2.Checked = False then
     begin
        Series2.Clear;
        Series2.Active := False;
     end;
end;


procedure TForm3.ButtonExitClick(Sender: TObject);
begin
     close;
end;


end.

(le fichier .save (un vulgaire fichier texte) est generer grave à une thread qui lit les valeur par RS232, les valeur peuvent etre constante ou variable ...)

Merci à vous.

Clercq.

6 réponses

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
9 juin 2006 à 23:10
Merci de fournir aussi la partie du code du thread en charge d'écrire le fichier.

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
Clercq Messages postés 19 Date d'inscription samedi 18 décembre 2004 Statut Membre Dernière intervention 14 juin 2006
12 juin 2006 à 09:27
Mon probleme n'a rien à voir avec la thread, je ne me rappel pas avoir
nommé mon post de cette manière. Mon probleme viens de la gestion du
graphique c'est tout,  m'a thread ecrit bien mon fichier donc rien
a voir.


Merci qd meme a toi de t'y etre interressé.
0
Clercq Messages postés 19 Date d'inscription samedi 18 décembre 2004 Statut Membre Dernière intervention 14 juin 2006
12 juin 2006 à 10:37
Bonjour, desolé pour le repost, mais le nom de ce sujet n'est vraiment pas significatif du probleme ...


voici ma thread,


////////////////////////////////////////////////////////////////////////////////////////////////////////////

unit threadEnvar;


interface


uses

  Classes, unit1, Sysutils, pcrInt00, windows;


type

  threadEnrCycl = class(TThread)

  private

    { Déclarations privées }

  protected

    procedure Execute; override;

  end;


implementation

uses

    progEnr;

{ Important : les méthodes et les propriétés des objets dans la VCL ne peuvent

  être utilisées que dans une méthode appelée en utilisant Synchronize, par exemple :


      Synchronize(UpdateCaption);


  où UpdateCaption pourrait être du type :


    procedure threadEnrCycl.UpdateCaption;

    begin

      Form1.Caption := 'Mis à jour dans un thread';

    end; }


{ threadEnrCycl }


procedure threadEnrCycl.Execute;

var

   myThreadEnrCycl : threadEnrCycl;

   saveVar : TextFile;

   ////////////////////

   i : integer;

   resultat : string;

   decimal : integer;

   locator: string;

   address: longint;

   lgth:  longint;

   buffer: PChar;

   mul : integer;

   bufAdd : string;

   tempAdd : string;

   addStr : string;

   sizeStr : integer;

   erreur : integer;

begin

  { Placez le code du thread ici}

     decimal := 0;

     resultat := '';

     addStr := '';

     bufAdd := '';

     tempAdd := '';

     tempAdd := Form1.listAttribTrans[(4 * Form1.cbListVar.ItemIndex) + 1];

     sizeStr := Length(tempAdd);

     if sizeStr < 8 then

     begin

        erreur := 8 - sizeStr;

        for i := 0 to erreur - 1 do

            bufAdd := bufAdd + '0';

     end;

     tempAdd := bufAdd + tempAdd;

     bufAdd := '';

     bufAdd := bufAdd + tempAdd[7];

     bufAdd := bufAdd + tempAdd[8];

     bufAdd := bufAdd + tempAdd[5];

     bufAdd := bufAdd + tempAdd[6];

     bufAdd := bufAdd + tempAdd[3];

     bufAdd := bufAdd + tempAdd[4];

     bufAdd := bufAdd + tempAdd[1];

     bufAdd := bufAdd + tempAdd[2];


     address := StrToInt('0x' + bufAdd);

     locator :=
'@canup_1_00A';                   
//'@TCU_2';

     if Form1.listAttribTrans[4*Form1.cbListVar.ItemIndex + 2] = 'NULL' then

        lgth := StrToInt(Form1.listAttribTrans[4*Form1.cbListVar.ItemIndex + 3])-1//4;//20;

     else

         lgth := StrToInt(Form1.listAttribTrans[4*Form1.cbListVar.ItemIndex + 3]);


          buffer := StrAlloc(20);


     AssignFile(saveVar, Form1.nameFile);

     ReWrite(saveVar); //Ouverture en mode ecriture

     while not (Time = StrToTime(Form1.debut)) and not terminated do

     begin

     end;

     while not (Time = (StrToTime(Form1.debut) + StrToTime(Form1.duree)) ) and not terminated do

     begin

    decimal := 0;

    WriteLn(saveVar, TimeToStr(Time);

          PCR_ReadMemoryArea(locator,

                            
address,

                            
lgth,

                            
buffer);

          if Form1.listAttribTrans[4*Form1.cbListVar.ItemIndex + 2] = 'NULL' then

          begin

               for i := 0 to (lgth - 1) do

               begin

                    if i = 0 then

                      
mul := 1

                    else

                       
mul := i*256;

                   
decimal := decimal + integer(buffer[i])*mul;

               end;

          end

          else

          begin

               for i := (lgth - 1) downto 0 do

               begin

                   
if i = (lgth - 1) then

                      
mul := 1

                    else

                       
mul := i*256;

                   
decimal := decimal + integer(buffer[i])*mul;

               end;

          end;

          WriteLn(saveVar, IntToStr(decimal));

      end;

    terminate;

    while not terminated

    begin

    end;

      closeFile(saveVar);

    Form4.close;

end;


end.

////////////////////////////////////////////////////////////////////////////////////////////////////////////


Cordialement


Clercq.
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
12 juin 2006 à 23:25
Je te cite : "(le fichier .save (un vulgaire fichier texte) est generer grave à une thread qui lit les valeur par RS232, les valeur peuvent etre constante ou variable ...)"

Quand deux processus accèdent au même fichier en même temps, il faut savoir gérer les collisions.
Bon, on se penche sur ton problème bientôt.

PS : Merci Ni69

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Clercq Messages postés 19 Date d'inscription samedi 18 décembre 2004 Statut Membre Dernière intervention 14 juin 2006
14 juin 2006 à 16:35
Merci Delphiprog :D.

Clercq.
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
21 juin 2006 à 23:02
Bon, on va essayer d'être clair (sans jeu de mots ).

J'ai essayé de reconstituer ton projet avec le peu que tu nous fournis et je n'y suis pas parvenu car  il est fait référence à des unités non fournies (pcrInt00, progEnr) dans l'unité threadEnvar.

Permets-moi de te te dire que ton code est très mal écrit puisque tu sembles ignorer que la VCL n'est pas "ThreadSafe" et tu adresses directement des objets (Form1, Form4) dans le corps de la méthode Execute du thread secondaire, au lieu de le faire avec la méthode Synchronize (précisément faite pour cela).
Une des solutions possibles serait de :
1- déclarer tes variables locales à la méthode Execute en tant que membres privés du thread
2- déclarer un constructeur prenant en paramètres deux arguments de type TForm1 et TForm4
et qu'à chaque fois que tu as besoin d'accèder aux fiches, tu le fasses dans le corps de la méthode Synchronize.
Une fois le code en place, si tu le souhaites, nous étudierons la manière de traiter les accès concurrentiels au fichier entre les différents threads (le principal et le secondaire).

Peux-tu nous expliquer pourquoi, dans la méthode Execute, on trouve le code suivant :
    terminate;
    while not terminated
    begin
    end;
(En passant, il manque un "do" )

Es-tu sur d'avoir fait fonctionner ton code au moins une fois ou est-ce une malencontreuse erreur de copier/coller ?

Globalement, il y a pas trop de maladresses ou d'erreurs qui font que nous ne pouvons pas te dépanner davantage pour le moment sans y passer des heures à tout remettre en place.

Si tu programmes vraiment dans la catégorie débutants comme tu l'as écrit plus haut, j'ai bien peur que le code ne soit pas encore à ta portée.

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
Rejoignez-nous