Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Unterschiede TTimer zwischen Delphi 7 und 2010? (https://www.delphipraxis.net/185804-unterschiede-ttimer-zwischen-delphi-7-und-2010-a.html)

JohannesK 7. Jul 2015 14:35

Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Hallo,

ich habe ein merkwürdiges Problem beim Wechsel eines Programms von D7 auf D2010. Das Programm ist komplett identisch übernommen, lediglich einige Komponenten für OPC-Zugriffe sind aktualisiert. Im Programm werden verschiedene Timer erstellt, die den Aufruf unterschiedlicher Erfassungsgruppen steuern. Die Timer sind jeweils in einer Klasse zusammengefasst.

Delphi-Quellcode:
  TSavetimer = class(TComponent)
    private
      STimer: TTimer;
      RTimer: TTimer;
      SInterval: integer;
      RInterval: integer;
      AInterval: integer;
    public
      constructor create(conn: TUniconnection; aSaveObj: TdOPCGroup);
      destructor destroy;
      procedure SaveTimerEvent(sender: TObject);
      procedure ReadTimerEvent(sender: TObject);
  end;

constructor TSavetimer.create(conn: TUniconnection; aSaveObj: TdOPCGroup);
begin
  inherited create(application);
  SaveObj := aSaveObj;
  STimer := TTimer.Create(self);
  STimer.Enabled := false;
  STimer.OnTimer := SaveTimerEvent;
  RTimer := TTimer.Create(self);
  RTimer.Enabled := false;
  RTimer.OnTimer := ReadTimerEvent;
end;

procedure TSavetimer.SaveTimerEvent(sender: TObject);
var tr: TSaveThread;
begin
   try
      tr := TSaveThread.Create(self);
      tr.FreeOnTerminate := false;
      tr.execute;
      repeat sleep(10) until tr.Terminated;
      tr.Free;
     except
       //
     end;
end;
Die Timer sind den Gruppen über einen entsprechenden Pointer zugeordnet. D7 läuft seit Jahren problemos, D2010 löst keine Timer aus.

Hat irgendjemand einen Tipp?

Photoner 7. Jul 2015 14:39

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Da fehlt noch was.

Delphi-Quellcode:
..Timer.Enabled := False;
Wo werden die Timer aktiviert? Was für ein Intervall? Wird mehrfach dein Savethread erzeugt obwohl du ihn nur einmal brauchst?

Mehr Fragen als Antworten :)

Morphie 7. Jul 2015 14:40

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Wo werden die Timer denn eingeschaltet? (Enabled := true)

edit: zu spät

JohannesK 7. Jul 2015 14:47

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Die Timer werden eingeschaltet sobald die gesamten Gruppen ferig definiert sind damit nicht ein timer in eine unfertige Definition reinfunkt.
Delphi-Quellcode:

  savetimer := TSavetimer.create(dm.uniconn, server.OPCGroups[i]);
  savetimer.Name := server.OPCGroups[i].Parent.Name + '_' + server.OPCGroups[i].Name;
  savetimer.GroupNo := strtoint(rightstr(server.OPCGroups[i].Name, length(server.OPCGroups[i].Name)-2));
  itdata := server.OPCGroups[i].opcitems[0].data;

  savetimer.SInterval := itdata^.intervall;
  savetimer.RInterval := itdata^.ReadIntervall;
  savetimer.AInterval := itdata^.LimitIntervall;

  savetimer.STimer.Interval := savetimer.SInterval;
  savetimer.RTimer.Interval := 30000;

  savetimer.Stimer.Enabled := true;  
  savetimer.Rtimer.Enabled := true;
Wie gesagt, der Code ist identisch mit dem in D7,am Ende der ganzen Aufruferei ist der Status enabled bei beiden Timern = true.
Das manuelle Aufrufen der Prozedur SaveTimerEvent funktioniert auch ohne Fehler.

@Photoner: Der Savethread braucht ein paar millisekunden und wird jedesmal wieder freigegeben (siehe hier):
Delphi-Quellcode:
procedure TSavetimer.SaveTimerEvent(sender: TObject);
var tr: TSaveThread;
begin
   try
      tr := TSaveThread.Create(self);
      tr.FreeOnTerminate := false;
      tr.execute;
      repeat sleep(10) until tr.Terminated;
      tr.Free;
     except
       //
     end;
end;

baumina 7. Jul 2015 14:59

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Stutzig macht mich, dass RTimer und STimer eigentlich private sind, du aber trotzdem von außen auf diese zugreifst, ist das denn alles in einer Unit? Weil sonst dürfte das nicht gehen.

JohannesK 7. Jul 2015 15:06

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Ja, das steht alles in einer unit.
Ausserdem sind die Timer ja der einen globalen Komponente zugeordnet in der der gesamte Ablauf stattfindet.

Die Prozeduren sind
SaveTimerEvent(sender: TObject);
ReadTimerEvent(sender: TObject);
sind public

Uwe Raabe 7. Jul 2015 15:07

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
OT: Ist TSaveThread wirklich eine Ableitung von TThread? Dann finde ich die Verwendung - insbesondere den Aufruf von Execute - ziemlich gewagt.

Abgesehen davon, wartest du ja sowieso in der repeat-Schleife auf die Beendigung des Threads. Warum dann überhaupt ein Thread?

Photoner 7. Jul 2015 15:12

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Gib doch testweise dem TSaveTimer eine "Aktiv" Property und setze das Enabled der TTimer auf Enabled.

In der Prozedur

Delphi-Quellcode:
procedure TSavetimer.SaveTimerEvent(sender: TObject);
var tr: TSaveThread;
begin
if not Aktiv then exit;

Aktiv := False;
.
.
.
Aktiv := True;
end
hat zwei Vorteile. Du kannst sehen ob die TTimer aktiv sind und es existiert immer nur ein Thread.

JohannesK 7. Jul 2015 15:20

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Zitat:

OT: Ist TSaveThread wirklich eine Ableitung von TThread? Dann finde ich die Verwendung - insbesondere den Aufruf von Execute - ziemlich gewagt.

Abgesehen davon, wartest du ja sowieso in der repeat-Schleife auf die Beendigung des Threads. Warum dann überhaupt ein Thread?
Der Thread deshalb, damit sich verschiedene Gruppen beim Abspeichern nicht über die Timeraufrufe in die Quere kommen.
Ich bin zugegebnermassen nicht besonders Thread-sicher :), warum ist der Aufruf von execute gewagt (ist aber auch schon ein bisschen off-topic).

Delphi-Quellcode:
  TSaveThread = class(TThread)
     private
       ExecGroup: TSavetimer;
    protected
       procedure execute; override;
      function DoSave: boolean;
    public
       constructor Create(aItem: TSavetimer);
      destructor destroy; override;
  end;

procedure TSaveThread.execute;
var itdata: PItemidentify;
    srv: TPrOPCClientReader;
    n: string;
    p: integer;
    m, m1: integer;
begin
 try

  with ExecGroup do
    begin
      if not GetTimeAllow then exit; // Prüfungen ob gespeichert werden soll
      if not GetTriggerAllow then exit;
    end;

    terminate;

  finally
    terminate;
  end;
end;

JohannesK 7. Jul 2015 15:23

AW: Unterschiede TTimer zwischen Delphi 7 und 2010?
 
Zitat:

Zitat von Photoner (Beitrag 1308029)
Gib doch testweise dem TSaveTimer eine "Aktiv" Property und setze das Enabled der TTimer auf Enabled.

hat zwei Vorteile. Du kannst sehen ob die TTimer aktiv sind und es existiert immer nur ein Thread.

Die Timer sind nach Ende der Definitionsfunktionen aktiv, das habe ich mit einer entsprechenden Rückmeldung überprüft, ich sehe drum in einer zusätzlichen Variablen keinen Vorteil. Ausserdem läuft das exakt gleiche Programm in D7


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:07 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz