首页 > 解决方案 > 我可以在`Inherited Create`之前做一些初始化吗?

问题描述

我想创建并启动一个线程,全部使用一个命令行TClientCopyThread.Create(...)。为此,我必须使用 来创建线程Suspended = False,以便它可以立即运行。我知道,当我编写一个constructor新对象时,首先我必须调用inherited Create以便创建对象的实例,然后进行初始化。但是在这里,如果我调用inherited线程将在没有初始化参数的情况下启动。我尝试inherited最后打电话,它似乎正在工作(我没有收到任何访问冲突),但我不确定这是否是巧合。

  TClientCopyThread = class(TThread)
  private
    OwnGUID: String;
    SrcPath, DestPath: String;
    Files: TFileNames;
    RemoveIt: Boolean;
  protected
    procedure Execute; override;
  public
    constructor Create(const GUID, ASrcPath, ADestPath: String;
     const FileNames: TFileNames; RemoveSrc: Boolean);
  end;

constructor TClientCopyThread.Create(const GUID, ASrcPath, ADestPath: String;
 const FileNames: TFileNames; RemoveSrc: Boolean);
var I: Integer;
begin
 SrcPath:=  Copy(ASrcPath, 1, Length(ASrcPath));
 DestPath:= Copy(ADestPath, 1, Length(ADestPath));
 SetLength(Files, Length(FileNames));
 for I:= 0 to High(Files) do
  Files[I]:= Copy(FileNames[I], 1, Length(FileNames[I]));
 RemoveIt:= RemoveSrc;
 FreeOnTerminate:= True;
 inherited Create;
end;

标签: multithreadingdelphidelphi-10.3-rio

解决方案


要回答您的具体问题 - 是的,您可以inherited Create在派生构造函数期间随时调用。它不需要是第一条语句(与inherited Destroy析构函数中的最后一条语句相同)。在调用任何构造函数之前,已经为类对象分配了全部内存,因此在调用inherited构造函数之前初始化派生类的成员是安全的。但是,从派生构造函数访问基类成员时,应inherited先调用构造函数进行初始化,然后再访问它们。

话虽如此,您对TThread构造函数如何工作的理解是完全错误的。从 Delphi 6 开始,基类TThread构造函数总是在挂起模式下创建底层操作系统线程,然后在所有构造函数完全退出TThread.AfterConstruction()后恢复线程,如果对象是用. 因此,自 2001 年 Delphi 6 发布以来,您声称调用with将立即启动线程运行的说法并不正确。您的构造函数退出之前,底层操作系统线程不会开始运行。因此,您的方法永远不会TThreadCreateSuspended=Falseinherited CreateCreateSuspended=FalseTClientCopyThread.Create()Execute()对未初始化的成员采取行动,无论您如何设置CreateSuspended.

您所描述的(在成员初始化之前运行的线程)是 Delphi 5 及更早版本中的一个错误,该错误已在 Delphi 6 中修复。


推荐阅读