I am learning how to use OmniThreadLibrary in Delphi XE2, i wonder if someone can show me how to cancel a parallel.foreach.
I read that I should use a cancellation token, but I cannot find an example of some sort on how to use it.
This is the original for loop inside the function.
function SomeFunction() : string;
begin
for value := 0 to length(listOfThings)-1 do
begin
Chain := Function1( listOfThings[value] );
if Evaluate( Chain , Solution) then
Parameters[value] := Solution
else
begin
Result := 'ERROR';
exit;
end;
end;
end;
And this is how I am using the Parallel.ForEach
function SomeFunction() : string;
begin
Parallel.ForEach(0, length(listOfThings)-1 ).Execute(
procedure (const value: integer)
var Chain : string;
begin
Chain := Function1(listOfThings[value]);
if Evaluate(Chain , Solution) then
Parameters[value] := Solution
else
begin
Result := 'ERROR'; //Here is where it won't work
exit;
end;
end
);
end;
Inside the Parallel.ForEach I can't do Result := 'ERROR'
because it is not captured inside the procedure, so I think if I can cancel the Parallel.ForEach and report that cancellation, then I can just assign Result := 'ERROR'
outside.
But I am new to OmniThreadLibrary and I don't know how to do such a thing, please help me :)
You need to use a cancellation token:
var
cancelToken: IOmniCancellationToken;
You obtain the cancellation token by calling CreateOmniCancellationToken
from the OtlSync
unit.
cancelToken := CreateOmniCancellationToken;
You then supply the token to the parallel loop:
Parallel.ForEach(...)
.CancelWith(cancelToken)
.Execute(...);
And you signal the cancellation token by calling its Signal
method.
cancelToken.Signal;
From outside the parallel loop you can use
cancelToken.IsSignaled
to detect that you cancelled. Or you can capture a boolean variable from the surrounding scope and pass the information through that variable.
The example here gives an illustration.