实现线程Terminate方法的覆盖

时间:2015-11-27 17:59:33

标签: multithreading delphi

我正在尝试覆盖虚拟的TThread :: Terminate方法,但是在设置Terminated标志后,我发现我的覆盖仅被调用。实现这个的正确方法是什么?

TTestThrd = class(TThread)
private
    { Private declarations }

protected
    { Protected declarations }
    procedure Execute(); override;
    procedure DoTerminate(); override;

public
    { Public declarations }
end;


procedure TTestThrd.Execute();
var
    bTerminated: Boolean;
begin
    // This is the main thread loop
    try
        while (not Terminated) do
            begin
            // Sleep or use TEvent::Waitfor...
            end;
    finally
        // Terminated (or exception) so free all resources...
        bTerminated := True;        // Why is this called...
    end;
end;

procedure TTestThrd.DoTerminate();
var
    bDoTerminateCalled: Boolean;
begin
    bDoTerminateCalled := True;     // ...before this?  
    inherited;
end;

2 个答案:

答案 0 :(得分:5)

据我了解,问题中缺少信息。阅读上一个问题(Alternative to sleep inside a thread)和评论记录非常重要。

您正在尝试安排调用Terminate来表示您的线程正在等待的事件。为了实现这一点,您需要将调用挂钩到Terminate。等待DoTerminateOnTerminate并不好,因为它们在线程程序完成后执行。

在现代版本的Delphi中,您可以覆盖TerminatedSet。这正是你所需要的。它是从Terminate内部触发的。

在旧版本的Delphi中,在此方法之前,无法通过Terminate方法通知。据我了解,这是关键点。您希望挂钩Terminate,并且在添加TerminatedSet之前,不存在此类挂钩。

如果您无法使用TerminatedSet,那么您需要在类上提供一个调用Terminate的方法,然后执行您必须执行的任何其他操作。例如:

procedure TMyThread.SignalAndTerminate;
begin
  FTerminationEvent.SetEvent;
  Terminate;
end;

答案 1 :(得分:1)

如果要在设置Terminate属性之前调用方法,则必须覆盖System.Classes.TThread.Terminate方法。
Terminate方法:

  

通过将Terminated属性设置为true来表示线程终止。

来自System.Classes.TThread.DoTerminate文档:

  

DoTerminate调用OnTerminate事件处理程序,但不终止该线程。

OnTerminate事件之前但在Terminate属性设置为True之后调用的另一个感兴趣的过程是System.Classes.TThread.TerminatedSet,它被声明为 {{ {}}}中的1}} abstract

我现在没有IDE,但我想如果你查看virtual类,你会发现TThread事件处理程序是在TThread属性之后触发的设置为OnTerminate