I wanted to realize a repetitive task in an OmniThreadLibrary worker task, that runs in another thread. The task should be executed every 3 seconds, for example.
Therefore I wrote a TOmniWorker
descendant with an instance of TTimer
as you can see below:
program Project14;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Vcl.ExtCtrls,
Vcl.Forms,
OtlTaskControl;
type
TMyTimerWorker = class(TOmniWorker)
strict private
FTimer: TTimer;
procedure DoOnTimer(Sender: TObject);
protected
function Initialize: Boolean; override;
procedure Cleanup; override;
end;
{ TMyTimerWorker }
procedure TMyTimerWorker.Cleanup;
begin
FTimer.Free;
inherited;
end;
procedure TMyTimerWorker.DoOnTimer(Sender: TObject);
begin
Beep;
end;
function TMyTimerWorker.Initialize: Boolean;
begin
Result := inherited;
if not Result then exit;
FTimer := TTimer.Create(nil);
FTimer.OnTimer := DoOnTimer;
FTimer.Interval := 3000;
FTimer.Enabled := True; // note: this isn't necessary, but is added to avoid hints that 'Enabled' might be 'False'
end;
var
LTimerWorker: IOmniWorker;
begin
try
LTimerWorker := TMyTimerWorker.Create;
CreateTask(LTimerWorker).Unobserved.Run;
while True do
Application.ProcessMessages;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
I set breakpoints in Initialize
and DoOnTimer
. Former executes well but latter won't be called at all. BTW: Cleanup
isn't called neither, so the task is still running.
What am I doing wrong? Is it impossible to use a TTimer
in an OTL task? If yes, why?
UPDATE: I found a workaround for TTimer
() but why does TTimer
approach not work?