作者:1500799277_a9483d_353 | 来源:互联网 | 2023-02-03 14:06
在柏林的Delphi 10.1中,我想添加一个可能性来停止我的问题中的响应式TParallel。&For循环。如何使TParallel。&For循环响应并将值存储在TList 中?。
循环计算值并将这些值存储在TList中。它与TTask.Run在单独的线程中运行以使其响应:
type
TCalculatiOnProject=class(TObject)
private
Task: ITask;
...
public
List: TList;
...
end;
procedure TCalculationProject.CancelButtonClicked;
begin
if Assigned(Task) then
begin
Task.Cancel;
end;
end;
function TCalculationProject.CalculateListItem(const AIndex: Integer): Real;
begin
//a function which takes a lot of calculation time
//however in this example we simulate the calculation time and
//use a simple alogorithm to verify the list afterwards
Sleep(30);
Result:=10*AIndex;
end;
procedure TCalculationProject.CalculateList;
begin
List.Clear;
if Assigned(Task) then
begin
Task.Cancel;
end;
Task:=TTask.Run(
procedure
var
LoopResult: TParallel.TLoopResult;
Lock: TCriticalSection;
begin
Lock:=TCriticalSection.Create;
try
LoopResult:=TParallel.&For(0, 1000-1,
procedure(AIndex: Integer; LoopState: TParallel.TLoopState)
var
Res: Real;
begin
if (Task.Status=TTaskStatus.Canceled) and not(LoopState.Stopped) then
begin
LoopState.Stop;
end;
if LoopState.Stopped then
begin
Exit;
end;
Res:=CalculateListItem(AIndex);
Lock.Enter;
try
List.Add(Res);
finally
Lock.Leave;
end;
end
);
finally
Lock.Free;
end;
if (Task.Status=TTaskStatus.Canceled) then
begin
TThread.Synchronize(TThread.Current,
procedure
begin
List.Clear;
end
);
end
else
begin
if LoopResult.Completed then
begin
TThread.Synchronize(TThread.Current,
procedure
begin
SortList;
ShowList;
end
);
end;
end;
end
);
end;
当前运行的计算任务应在以下情况下停止
计算重新开始
用户单击取消按钮
我加了
if Assigned(Task) then
begin
Task.Cancel;
end;
在单击“取消”按钮时的开始procedure TCalculationProject.CalculateList
和procedure TCalculationProject.CancelButtonClicked
调用中。
循环停止
if (Task.Status=TTaskStatus.Canceled) and not(LoopState.Stopped) then
begin
LoopState.Stop;
end;
if LoopState.Stopped then
begin
Exit;
end;
并使用清除清单
if (Task.Status=TTaskStatus.Canceled) then
begin
TThread.Synchronize(TThread.Current,
procedure
begin
List.Clear;
end
);
end
当我重新开始计算时,这不起作用。然后,两个计算任务正在运行。我尝试添加一个Task.Wait
after Task.Cancel
来等待任务完成,然后再开始新的计算,但是没有成功。
实现这种取消/停止功能的正确的完全线程安全的正确方法是什么?