TimedTask := Parallel.TimedTask.Execute(
procedure(const task: IOmniTask)
begin
// ...
end);
In the background, Parallel.TimedTask calls TOmniTimedTask.Create() which calls CreateTask(TOmniTimedTaskWorker.Create(), 'Timed task').Unobserved.Run
The problem is that TOmniTimedTaskWorker is private to the OtlParallel unit, which means you cannot take that call out without also copying that class.
This code fragment creates a Timed task which every 5 seconds (5000 milliseconds) sends a message MSG_WATCHDOG to its owner.
3.15.1 IOmniTimedTask interface
The Parallel.TimedTask function returns an IOmniTimedTask interface which is used to configure and control a Timed task.
type
TOmniTaskDelegate = reference to procedure(const task: IOmniTask);
IOmniTimedTask = interface
function Every(interval_ms: integer): IOmniTimedTask;
function Execute(const aTask: TProc): IOmniTimedTask; overload;
function Execute(const aTask: TOmniTaskDelegate): IOmniTimedTask; overload;
procedure ExecuteNow;
procedure Start;
procedure Stop;
function TaskConfig(const config: IOmniTaskConfig): IOmniTimedTask;
function Terminate(maxWait_ms: cardinal): boolean;
function WaitFor(maxWait_ms: cardinal): boolean;
property Active: boolean;
property Interval: integer;
end;
Every sets the timer interval (in milliseconds). Interval must be a positive number. If you set it to a value which is less than or equal to zero, the timer will be disabled. (It is, however, advisable to use Stop or Active := false for this purpose as that more clearly states the intention of the code.)
When a timed task is created, its interval is set to 0 ms.
You can inspect and modify the interval by using the Interval property. Setting an interval by assigning a value to this property (Interval := value;) is equivalent to calling Every(value).
Execute specifies the code that will be called each Interval milliseconds (timer event handler code). This can be a parameter-less anonymous method (or normal procedure, or an object method) or procedure/method/anonymous method accepting one parameter of type IOmniTask which holds the interface of the background task executing the timer method.
After you set an interval (even if the current value is equal to the previous value), the background task will wait for Interval milliseconds before calling the timer event handler code.
If you want to execute timer event handler immediately, call the ExecuteNow method. This will also reset the timer so that next automatic invocation of the timer event handler will occur Interval milliseconds from now.
Start will start (enable) the timer. To stop (disable) the timer call the Stop method. Current state of the timer is available via the Active property.
You can also start/stop a timer by changing the Active property. Setting Active := true is equivalent to calling Start and setting Active := false is equivalent to calling Stop.
A timer is automatically started (enabled) when you call Execute – if and only if the Interval has already been set.
If you want to create a stopped timer with a very small Interval value, it is advisable to use the following pattern:
Calling Terminate will stop the timed task. If it stops in maxWait_ms, True is returned, False otherwise. WaitFor waits for the task to stop (without commanding it to stop beforehand so you would have to call Terminate before WaitFor) and returns True/False just as Terminate does.
It is usually enough to just set the IOmniTimedTask instance to nil as that effectively calls the Terminate(INFINITE).
I need to do some more research in the WaitFor behaviour in combination with the Interval, especially when the task takes longer than an Interval number of milliseconds.