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)