【问题标题】:thread onterminate - help writing the event线程终止 - 帮助编写事件
【发布时间】:2013-05-31 21:11:53
【问题描述】:

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

在我添加的线程中

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

然后在应用中...

Button1Click...
begin
  SearchThread.Terminate;
end;

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

谁能给我这个事件的代码sn-p。 Component 中有 Pause 和 Resume 事件,但没有 Abort。

谢谢。

【问题讨论】:

  • How to kill a thread in delphi? 的可能重复项
  • 您似乎对如何终止线程有正确的想法。那么你的问题是什么?如何编写自己的事件以在注册终止标志时调用?您的问题不清楚。
  • 要确定您的线程是正常终止还是被强制执行,请在您的执行中以不同的方式设置 tthread.retvalue。在 onterminate 事件中,可以读取此值。另请参阅delphipages.com/forum/showthread.php?t=209703
  • @TonyHopkinson:谢谢,但这就是我从那里得到代码来做我迄今为止所做的事情的地方。我需要一个提前终止的通知事件。
  • @Glenn1234:正如我刚才对托尼所说,我需要一些通知给我的程序,告诉我它提前终止了。我有几个在搜索过程中被禁用的列表框,我需要在正常执行时启用它们.

标签: multithreading delphi delphi-5


【解决方案1】:

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

【讨论】:

  • 谢谢,但我没那么聪明。 :) 该组件没有直接挂钩的 OnTerminate 或 DoTerminate 事件,因此我不确定如何编写代码来执行您的建议。我以前从未处理过线程,我只使用它来满足我的需要。我没有时间花在学习和理解线程上。我在 15 年的编程中没有使用过它们,在可预见的未来,我认为它们在我的正常工作线上没有用处。这就是为什么我要一个代码 sn-p。
  • 如果 TmFileScan 组件是设计时组件,它不能是直接的 TThread 类后代,但它在内部实现了 TThread 类,这反过来意味着此答案不适用于你。如果您正在使用 TThread 类后代,它将适用。如果它是具有内部线程的组件,则需要将该内部 TThread 类公开,或者该组件将直接发布一些终止事件(或者至少更具体地公开)。
  • @TLama:考虑到他在问题中声明他可以访问实际线程,并且已经对该线程的代码进行了修改,这个答案确实适用。
猜你喜欢
  • 2015-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
相关资源
最近更新 更多