如何取消IOmniParallelSimpleLoop?

时间:2018-12-17 08:50:07

标签: delphi delphi-10.2-tokyo omnithreadlibrary

我开始将OTL用于一个简单的项目,但是我目前停留在停止和重新启动一个简单的并行循环上。

用例

用户能够通过按下按钮来启动查询以解析IP地址列表的主机名。在任何时候,他都可以按下刷新按钮,该按钮将停止当前循环(CancelParallelResolveHostnames)并重新启动主机名解析(StartParallelResolveHostnames)。

但是在我所有的实现中,可执行文件在等待FParallelResolveHostnamesWait或只是尝试将FParallelResolveHostnames设置为nil时都处于死锁状态。

我还注意到取消循环时未调用OnStop回调。这是正常行为吗?

参考

示例代码

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;

示例项目:

0 个答案:

没有答案