![]() |
Delphi-Version: XE2
Thread + Timer, Einbinden von TimerThread.pas
Hallo Sir Rufo,
kannst du mir mal kurz die Anwendung deiner Unit TimerThread.pas ![]() 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 |
AW: Thread + Timer, Einbinden von TimerThread.pas
Jupp, dass nach dem
Delphi-Quellcode:
noch einmal
Enabled := False
Delphi-Quellcode:
aufgerufen wird, liegt daran, dass ich vergessen habe im Setter von
ExecuteTimed
Delphi-Quellcode:
den Event auszulösen.
Enabled
Habe ich jetzt mal geändert und zusätzlich dahingehend erweitert, dass der Event nur bei einer echten Änderung auslöst (
Delphi-Quellcode:
und
Interval
Delphi-Quellcode:
).
Enabled
Ein kleiner Fehler war auch noch im
Delphi-Quellcode:
, da wurde der Wert
Execute
Delphi-Quellcode:
nicht benutzt :oops:
LInterval
Zur Verwendung: Am sinnvollsten ist es sich von dieser Klasse eine neue Klasse abzuleiten.
Delphi-Quellcode:
Hier die korrigierte Version der Unit:
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.
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. |
AW: Thread + Timer, Einbinden von TimerThread.pas
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 |
AW: Thread + Timer, Einbinden von TimerThread.pas
Jo, stimmet, da fehlte im
Delphi-Quellcode:
doch tatsächlich
Create
Delphi-Quellcode:
:)
FEnabled := TIMERTHREAD_ENABLED_DEFAULT;
Ist jetzt auch drin ;) |
AW: Thread + Timer, Einbinden von TimerThread.pas
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 |
AW: Thread + Timer, Einbinden von TimerThread.pas
Im
Delphi-Quellcode:
wird doch
Execute
Delphi-Quellcode:
überprüft
Enabled
Delphi-Quellcode:
Noch mehr prüfen? Worauf und wozu? ;)
if Enabled then
LInterval := Interval else LInterval := INFINITE; Wenn ein Thread mit
Delphi-Quellcode:
beendet wurde, dann ist der durch mit dem Thema und du musst den Thread komplett neu erstellen. Ein Neustart nach
Terminate
Delphi-Quellcode:
ist da nicht vorgesehen.
Terminate
Wo ist denn da
Delphi-Quellcode:
in dem Source? :gruebel:
ResetEvent
|
AW: Thread + Timer, Einbinden von TimerThread.pas
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 |
AW: Thread + Timer, Einbinden von TimerThread.pas
Zitat:
Delphi-Quellcode:
Die
FCS.Enter:
try if FEnabled then LInterval := FInterval else LInterval := INFINITE; finally FCS.Leave; end; ![]() Bei Threads gibt es neben dem es funktioniert (kompiliert und ist auch mal gelaufen) auch noch ein es funktioniert gesichert immer ;) |
AW: Thread + Timer, Einbinden von TimerThread.pas
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 |
AW: Thread + Timer, Einbinden von TimerThread.pas
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; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz