Yann Papouin
Yann Papouin

Reputation: 31

How to cancel an IOmniParallelSimpleLoop?

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

Answers (0)

Related Questions