使用Delphi-v5和一个在线程中运行的组件(TmFileScan - 感谢Mats),我希望能够优雅地终止线程。经过大量的搜索和阅读后,我已经能够终止它,但我需要一个事件来处理中止后的一些屏幕清理。
在线程中我添加了
while not(Terminated) do // Iterating about a zillion times :)
...
然后在应用程序中......
Button1Click...
begin
SearchThread.Terminate;
end;
它运作良好。我在现有OnReady事件中清理了屏幕,当线程正常完成时会触发该事件。但是从未看到Thread是否被终止,所以我需要向组件添加OnAbort事件。
有人可以给我一个该事件的代码片段。组件中有Pause和Resume事件,但没有Abort。
谢谢。
答案 0 :(得分:3)
TThread
班级有OnTerminate
个活动。它由虚拟TThread.DoTerminate()
方法触发,该方法在Execute()
退出后调用,无论Execute()
是正常退出还是通过未捕获的异常退出。我建议覆盖DoTerminate()
,如果OnAbort
属性为True或Terminated
属性不为n,则触发FatalException
事件,并触发OnReady
事件,否则。
更新:假设您使用的是this TmFileScan component,我建议您进行以下修改,以便始终触发OnReady
事件:
TSearchThread = class(TThread)
private
...
protected
...
procedure DoTerminate; override; // <-- add this
public
destructor Destroy; override; // <-- add this
end;
constructor TSearchThread.Create(Owner: TmFileScan; SubDir, Started: Boolean;
FilePaths, Filter: TStrings; fOnFileFound: TOnFileFoundEvent;
fOnReady: TOnReadyEvent);
begin
inherited Create(true);
...
ffList := TStringList.Create; // <-- add this
...
Resume;
end;
// add this
destructor TSearchThread.Destroy;
begin
ffList.Free;
inherited Destroy;
end;
procedure TSearchThread.Execute;
var
...
begin // function FindFile
// remove this
{
ffList:= TStringList.Create;
try
while not Terminated do
begin
}
for q:= 0 to ffPaths.Count - 1 do
begin
if Terminated then Break; // <-- add this
for n:= 0 to ffFilters.Count - 1 do
begin
if Terminated then Break; // <-- add this
Spec:= ffFilters[n];
RFindFile(BackSlashFix(ffPaths[q]));
end;
end;
// remove this
{
Synchronize(Ready); // <-- remove this
Terminate;
end;
finally
ffList.Free;
end;
}
end;
// add this
procedure TSearchThread.DoTerminate;
begin
Synchronize(Ready);
inherited;
end;