-1

使用 Delphi-v5 和一个在线程中运行的组件(TmFileScan -- 感谢 Mats),我希望能够优雅地终止线程。经过大量搜索和阅读后,我已经能够终止它,但我需要一个事件来处理中止后的一些屏幕清理。

在我添加的线程中

while not(Terminated) do // Iterating about a zillion times :)
  ...

然后在应用...

Button1Click...
begin
  SearchThread.Terminate;
end;

它工作得很好。我在线程正常完成时触发的现有 OnReady 事件中清理屏幕。但是从来没有看到线程是否被终止,所以我需要向组件添加一个 OnAbort 事件。

有人可以给我那个事件的代码片段吗?组件中有 Pause 和 Resume 事件,但没有 Abort。

谢谢你。

4

1 回答 1

3

该类TThread有一个OnTerminate可用的事件。它由虚拟TThread.DoTerminate()方法触发,在退出后调用Execute(),无论是Execute()正常退出还是通过未捕获的异常退出。如果属性为 True 或属性不为零,我建议覆盖DoTerminate()并让它触发事件,否则触发事件。OnAbortTerminatedFatalExceptionOnReady

更新:假设您正在使用此 TmFileScan 组件,那么我建议您进行以下修改,以便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;
于 2013-05-31T21:39:55.920 回答