AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Thread + Timer, Einbinden von TimerThread.pas

Ein Thema von MarLe · begonnen am 10. Sep 2014 · letzter Beitrag vom 3. Jan 2018
Antwort Antwort
Seite 1 von 5  1 23     Letzte » 
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#1

Thread + Timer, Einbinden von TimerThread.pas

  Alt 10. Sep 2014, 15:10
Delphi-Version: XE2
Hallo Sir Rufo,

kannst du mir mal kurz die Anwendung deiner Unit TimerThread.pas http://www.delphipraxis.net/1270100-post13.html erläutern (wie muss ich die einbinden).
Ich habe bisher Threads noch nicht verwendet, zwar hier Vieles gelesen, aber auch nicht alles verstanden.
Bin mir auch nicht sicher ob die Unit für mein Prog passend ist. Ich möchte in meinem Prog zyklisch z.B. alle 5 Minuten aus einer Textdatei Werte holen, die dann vorhalten/aufbereiten um diese dann im Prog zu verwenden. Mir geht's jetzt mehr ums Prinzip nicht um den Feinschliff.
Vielen Dank im voraus.

Starten/Stoppen tue ich den Ablauf über das Property .Enabled;
Den zyklisch auszuführenden Code habe ich bei .ExecuteTimed plaziert.
Muss ich da auch noch Terminated abfragen?
Soweit scheint es zu funktionieren, wenn ich stoppe wird aber noch ein Durchlauf gemacht.

Gruß MarLe

Geändert von MarLe (10. Sep 2014 um 16:31 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 10. Sep 2014, 17:47
Jupp, dass nach dem Enabled := False noch einmal ExecuteTimed aufgerufen wird, liegt daran, dass ich vergessen habe im Setter von Enabled den Event auszulösen.

Habe ich jetzt mal geändert und zusätzlich dahingehend erweitert, dass der Event nur bei einer echten Änderung auslöst (Interval und Enabled ).

Ein kleiner Fehler war auch noch im Execute , da wurde der Wert LInterval nicht benutzt

Zur Verwendung: Am sinnvollsten ist es sich von dieser Klasse eine neue Klasse abzuleiten.
Delphi-Quellcode:
unit MyTimerThread;

interface

uses
  TimerThread;

type
  TMyTimerThread = class( TTimerThread )
  protected
    procedure ExecuteTimed; override;
  end;

implementation

procedure TMyTimerThread.ExecuteTimed;
begin
  // hier jetzt der eigene Code rein
end;

end.
Hier die korrigierte Version der Unit:
Delphi-Quellcode:
unit TimerThread;

interface

uses
  System.Classes,
  System.SyncObjs;

const
  TIMERTHREAD_INTERVAL_DEFAULT = 1000;
  TIMERTHREAD_ENABLED_DEFAULT = True;

type
  TTimerThread = class( TThread )
  private
    FCS : TCriticalSection;
    FEvent : TEvent;
    FInterval : Cardinal;
    FEnabled : Boolean;
    procedure SetInterval( const Value : Cardinal );
    function GetInterval : Cardinal;
    procedure SetEnabled( const Value : Boolean );
    function GetEnabled : Boolean;
  protected
    procedure Execute; override; final;
    procedure ExecuteTimed; virtual;
    // ACHTUNG! Das gibt es erst ab Delphi XE2
    procedure TerminatedSet; override;
  public
    constructor Create;
    destructor Destroy; override;

    property Interval : Cardinal read GetInterval write SetInterval default TIMERTHREAD_INTERVAL_DEFAULT;
    property Enabled : Boolean read GetEnabled write SetEnabled default TIMERTHREAD_ENABLED_DEFAULT;
  end;

implementation

{ TTimerThread }

constructor TTimerThread.Create;
begin
  FCS := TCriticalSection.Create;
  FEvent := TEvent.Create( nil, False, False, '' );
  inherited Create( False );
  FInterval := TIMERTHREAD_INTERVAL_DEFAULT;
  FEnabled := TIMERTHREAD_ENABLED_DEFAULT;
end;

destructor TTimerThread.Destroy;
begin

  inherited;
  FEvent.Free;
  FCS.Free;
end;

procedure TTimerThread.Execute;
var
  LInterval : Cardinal;
begin
  inherited;
  while not Terminated do
    begin
      if Enabled then
        LInterval := Interval
      else
        LInterval := INFINITE;

      if FEvent.WaitFor( LInterval ) = TWaitResult.wrTimeout
      then
        ExecuteTimed;
    end;
end;

procedure TTimerThread.ExecuteTimed;
begin

end;

function TTimerThread.GetEnabled : Boolean;
begin
  FCS.Enter;
  try
    Result := FEnabled;
  finally
    FCS.Leave;
  end;
end;

function TTimerThread.GetInterval : Cardinal;
begin
  FCS.Enter;
  try
    Result := FInterval;
  finally
    FCS.Leave;
  end;
end;

procedure TTimerThread.SetEnabled( const Value : Boolean );
begin
  FCS.Enter;
  try
    if Value <> FEnabled then
    begin
      FEnabled := Value;
      FEvent.SetEvent;
    end;
  finally
    FCS.Leave;
  end;
end;

procedure TTimerThread.SetInterval( const Value : Cardinal );
begin
  FCS.Enter;
  try
    if Value <> FInterval then
    begin
      FInterval := Value;
      FEvent.SetEvent;
    end;
  finally
    FCS.Leave;
  end;
end;

procedure TTimerThread.TerminatedSet;
begin
  inherited;
  FEvent.SetEvent;
end;

end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (11. Sep 2014 um 09:07 Uhr)
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#3

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 11. Sep 2014, 08:22
Guten Morgen,

den Fehler im Execute hatte ich beim "Studieren" der Unit auch schon korrigiert.
Die anderen Änderungen habe ich umgesetzt und jetzt schaut's gut aus, Danke für die Unterstützung.

Noch eine Frage zu der Vorbelegung TIMERTHREAD_ENABLED_DEFAULT = True;
Müsste der Ablauf nach einem .Create nicht gleich starten, bei mir startet es erst nach einem zusätzlichen .Enabled := True;

Gruß MarLe
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 11. Sep 2014, 09:08
Jo, stimmet, da fehlte im Create doch tatsächlich FEnabled := TIMERTHREAD_ENABLED_DEFAULT;

Ist jetzt auch drin
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 11. Sep 2014, 11:33
Jetzt habe ich noch zwei Verständnisfragen:

Soll im .Execute nicht auf FEnabled abgefragt werden, oder ist das egal?
Ich habe jetzt mal zum Testen auch den Thread gestoppt, mit .Terminate;
Wie starte ich diesen wieder mit .Start; (was macht .ResetEvent) hat so nicht funktioniert ?

Gruß MarLe
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 11. Sep 2014, 11:51
Im Execute wird doch Enabled überprüft
Delphi-Quellcode:
      if Enabled then
        LInterval := Interval
      else
        LInterval := INFINITE;
Noch mehr prüfen? Worauf und wozu?

Wenn ein Thread mit Terminate beendet wurde, dann ist der durch mit dem Thema und du musst den Thread komplett neu erstellen. Ein Neustart nach Terminate ist da nicht vorgesehen.

Wo ist denn da ResetEvent in dem Source?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#7

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 11. Sep 2014, 12:56
Ich kann ja auch auf FEnabled (statt Enabled) abfragen, funktioniert auch, deshalb die Frage.
Die zweite Frage hat sich erledigt, da habe ich woanders was von ResetEvents gelesen, aber falsch aufgefasst.

Gruß MarLe
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 11. Sep 2014, 13:15
Ich kann ja auch auf FEnabled (statt Enabled) abfragen, funktioniert auch, deshalb die Frage.
Ja kann man, aber dann so:
Delphi-Quellcode:
  FCS.Enter:
  try
      if FEnabled then
        LInterval := FInterval
      else
        LInterval := INFINITE;
  finally
    FCS.Leave;
  end;
Die Delphi-Referenz durchsuchenTCriticalSection schützt vor dem gleichzeitigen Zugriff von unterschiedlichen Threads. Bei der Abfrage über die Eigenschaft ist das im Getter und Setter schon drin (siehe Source) und darum kann man die Eigenschaften gefahrlos benutzen, ansonsten muss man sich um den Schutz selber kümmern.

Bei Threads gibt es neben dem es funktioniert (kompiliert und ist auch mal gelaufen) auch noch ein es funktioniert gesichert immer
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (11. Sep 2014 um 13:18 Uhr)
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#9

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 11. Sep 2014, 13:26
Ok alles klar, so wie du es beschrieben hast habe ich es auch gemeint, ist quasi egal ob ich auf FEnabled oder Enabled abfrage.
"es funktioniert gesichert immer" ist mir natürlich am liebesten!

Gruß Marle
  Mit Zitat antworten Zitat
LTE5

Registriert seit: 13. Nov 2017
355 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: Thread + Timer, Einbinden von TimerThread.pas

  Alt 2. Jan 2018, 01:38
Weile ich ein anderes Thema damit nicht belasten möchte hier die Frage.

Ist dieser TimerThread mit Warte-Events nicht anderes als ein normaler TThread mit einer while-Schleife und einem Sleep(1234) im Execute-Teil?
Nur.. mit Events eben.. und nicht mit Sleep?


Wie sähe das hier mit dem TimerThread aus?
Delphi-Quellcode:
procedure TMyNormalThread.Execute;
begin
  while not Terminated do
   begin
    Sleep(1000);

    if 1 = 2 then
     // viel zu tun
   end;
end;

Geändert von LTE5 ( 2. Jan 2018 um 01:44 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:44 Uhr.
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