From the TParallel.For
documentation:
If control of the iteration itself is needed from the iterator event, the iterator event handler should be one using the TParallel.TLoopState
parameter. When present, the event handler will be given an instance of TParallel.TLoopState
from which state information from Faulted
,Stopped
, or ShouldExit
can be monitored, or the iteration loop itself can be controlled with the Break
or Stop
methods.
The way to keep track of LoopState is to use a method with the following signature:
TIteratorStateEvent =
procedure (Sender: TObject; AIndex: Integer; const LoopState: TLoopState) of object;
Or use its anonymous version:
class function &For(AStride, ALowInclusive, AHighInclusive: Integer;
const AIteratorEvent: TProc<Integer, TLoopState>; APool: TThreadPool): TLoopResult;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the documentation fails the easiest way is to search the source code for the class, or let code completion do the work.
TLoopState = class
private [...]
public
procedure Break;
procedure Stop;
function ShouldExit: Boolean; <<-- this looks useful
property Faulted: Boolean read GetFaulted;
property Stopped: Boolean read GetStopped; <<-- or this
property LowestBreakIteration: Variant read GetLowestBreakIteration;
end;
Example:
procedure TForm1.btnParallelForClick(Sender: TObject);
var
Tot: Integer;
SW: TStopwatch;
begin
try
// counts the prime numbers below a given value
Tot :=0;
SW :=TStopWatch.Create;
SW.Start;
//Use a method that supports LoopState
TParallel.For(2,1,Max,procedure(I:Int64; State: TLoopState)
begin
//check loopstate every now and again.
if State.ShouldExit then exit;
if IsPrime(I) then TInterlocked.Increment(Tot);
end);
SW.Stop;
Memo1.Lines.Add(Format('Parallel For loop. Time (in milliseconds): %d - Primes found: %d', [SW.ElapsedMilliseconds,Tot]));
except on E:EAggregateException do
ShowMessage(E.ToString);
end;
end;