我开始将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;
示例项目: