ttw_fmx_v10/utils/uMyTimer.pas

159 lines
3.1 KiB
Plaintext

unit uMyTimer;
interface
uses
System.Classes, System.SyncObjs, System.SysUtils;
type
TTimerExec = procedure(Sender: TObject; const txt: string; o: Boolean) of object;
TMyTimerThread = class(TThread)
private
FEvent: TEvent;
FCriticalSection: TCriticalSection;
FInterval: Integer;
FText: string;
FFlagO: Boolean;
FEnabled: Boolean;
FOnTimerExec: TTimerExec;
procedure SyncTimerEvent;
protected
procedure Execute; override;
public
constructor Create(AIntervalMinutes: Integer; const AText: string; AFlagO: Boolean);
destructor Destroy; override;
procedure StartT;
procedure StopT;
procedure TerminateAndDestroy;
procedure Update(AIntervalMinutes: Integer; const AText: string; AFlagO: Boolean);
property OnTimerExec: TTimerExec read FOnTimerExec write FOnTimerExec;
end;
implementation
{ TMyTimerThread }
constructor TMyTimerThread.Create(AIntervalMinutes: Integer; const AText: string; AFlagO: Boolean);
begin
inherited Create(True);
FreeOnTerminate := False;
FEvent := TEvent.Create(nil, True, False, '');
FCriticalSection := TCriticalSection.Create;
FInterval := AIntervalMinutes * 60 * 1000;
FText := AText;
FFlagO := AFlagO;
FEnabled := False;
end;
destructor TMyTimerThread.Destroy;
begin
StopT;
Terminate;
FEvent.SetEvent;
if not Suspended then
WaitFor;
FreeAndNil(FEvent);
FreeAndNil(FCriticalSection);
inherited;
end;
procedure TMyTimerThread.Execute;
var
WaitResult: TWaitResult;
LocalInterval: Integer;
begin
while not Terminated do
begin
FCriticalSection.Enter;
try
if FEnabled then
LocalInterval := FInterval
else
LocalInterval := INFINITE;
finally
FCriticalSection.Leave;
end;
WaitResult := FEvent.WaitFor(LocalInterval);
FCriticalSection.Enter;
try
if FEnabled and (WaitResult = wrTimeout) then
begin
if Assigned(FOnTimerExec) then
SyncTimerEvent;
end;
finally
FCriticalSection.Leave;
end;
FEvent.ResetEvent;
end;
end;
procedure TMyTimerThread.StartT;
begin
FCriticalSection.Enter;
try
FEnabled := True;
Suspended:=false;
finally
FCriticalSection.Leave;
end;
if Suspended then
Start;
FEvent.SetEvent;
end;
procedure TMyTimerThread.StopT;
begin
FCriticalSection.Enter;
try
FEnabled := False;
Suspended:=true;
finally
FCriticalSection.Leave;
end;
FEvent.SetEvent;
end;
procedure TMyTimerThread.SyncTimerEvent;
var
LText: string;
LFlag: Boolean;
begin
FCriticalSection.Enter;
try
LText := FText;
LFlag := FFlagO;
finally
FCriticalSection.Leave;
end;
if Assigned(FOnTimerExec) then
FOnTimerExec(Self, LText, LFlag);
end;
procedure TMyTimerThread.TerminateAndDestroy;
begin
StopT;
Terminate;
Free;
end;
procedure TMyTimerThread.Update(AIntervalMinutes: Integer; const AText: string; AFlagO: Boolean);
begin
FCriticalSection.Enter;
try
FInterval := AIntervalMinutes * 60 * 1000;
FText := AText;
FFlagO := AFlagO;
finally
FCriticalSection.Leave;
end;
FEvent.SetEvent;
end;
end.