Reputation: 31
I'm starting using the OTL for a simple project but I'm currently stuck at stopping and restarting a simple parallel loop.
Use case
The user is able to start a query to resolve hostnames of a list of IP address by pressing a button. At any moment, he can press a refresh button that will stop the current loop (CancelParallelResolveHostnames) and restart hostname resolution (StartParallelResolveHostnames).
But in all my implementations, the executable is dead locked at waiting for the FParallelResolveHostnamesWait or simply when I try to set FParallelResolveHostnames to nil.
I also noticed that the OnStop callback is not called when the loop is canceled. Is it the normal behaviour ?
References
Sample code
var
FAddressToProcess: TStringList;
FParallelResolveHostnames: IOmniParallelSimpleLoop;
FParallelResolveHostnamesCancelToken: IOmniCancellationToken;
FParallelResolveHostnamesWait: IOmniWaitableValue;
procedure TGuiConnections.StartParallelResolveHostnames;
var
TaskConfig: IOmniTaskConfig;
begin
FParallelResolveHostnamesWait := CreateWaitableValue;
FParallelResolveHostnamesCancelToken := CreateOmniCancellationToken;
TaskConfig := Parallel.TaskConfig;
TaskConfig.SetPriority(TOTLThreadPriority.tpLowest);
FParallelResolveHostnames := Parallel //
.For(0, FAddressToProcess.Count - 1) //
.TaskConfig(TaskConfig) //
.CancelWith(FParallelResolveHostnamesCancelToken) //
.NoWait //
.OnStop(
procedure
begin
FParallelResolveHostnamesWait.Signal;
end); //
FParallelResolveHostnames.NoWait.Execute(
procedure(i: Integer)
begin
ResolveHostname(i, FAddressToProcess[i]);
end);
end;
procedure TGuiConnections.CancelParallelResolveHostnames;
begin
if Assigned(FParallelResolveHostnamesCancelToken) then
begin
FParallelResolveHostnamesCancelToken.Signal;
end;
if Assigned(FParallelResolveHostnamesWait) then
begin
FParallelResolveHostnamesWait.WaitFor();
FParallelResolveHostnamesWait := nil;
FParallelResolveHostnames := nil;
FParallelResolveHostnamesCancelToken := nil;
end;
end;
Sample projects:
Upvotes: 0
Views: 93