1

ここで少し問題があります。TPersistent クラスを継承するカスタム クラスがあり、このカスタム クラスの内部 (プライベート セクション) には、オーバーライドされた Execute メソッドを使用して (1000 ミリ秒ごとに) 起動するカスタム TThread があります。2つのカスタムクラスを新しいユニットに移動するまで、すべてがうまく機能します...

type
  TMyThread= class(TThread)
  protected
   procedure Execute; override;
  end;

  TMyClass = class(TPersistent)
  private
   T: TMyThread;
  protected
   constructor Create;
  public
   destructor Destroy; override;
  end;


implementation

procedure TMyThread.Execute;
begin
 while not Self.Terminated do begin
  Sleep(1000);
  MessageBox(0, 'test', nil, MB_OK)
 end;
end;

constructor TMyClass.Create;
begin
 inherited Create;
 t := TMyThread.Create(False);
end;

destructor TMyClass.Destroy;
begin
 t.Terminate;
 t.WaitFor;
 FreeAndNil(t);
 inherited Destroy;
end;

上記のコードはメイン プロジェクト ユニットではうまく機能しますが、新しいユニットに移動するとスレッド コードが機能しなくなり、TMyClass オブジェクトを解放しようとすると AV が発生します。スレッドがまったく構築されていないと思います。そのため、スレッドを解放しようとすると AV が発生します...しかし、なぜですか? コードがどのユニットにあるかは問題ではありません...

ユニット1:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  p: TMyClass;

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
begin
 p.Free; //Getting an AV
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 p := TMyClass.Create;
end;

end.

ユニット2:

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TMyThread = class(TThread)
  protected
   procedure Execute; override;
  end;

  TMyClass = class(TPersistent)
  private
   T: TMyThread;
  protected
   constructor Create;
  public
   destructor Destroy; override;
  end;


implementation

procedure TMyThread.Execute;
begin
 while not Self.Terminated do begin
  Sleep(1000);
  MessageBox(0, 'test', nil, MB_OK)
 end;
end;

constructor TMyClass.Create;
begin
 inherited Create;
 t := TMyThread.Create(False);
end;

destructor TMyClass.Destroy;
begin
 t.Terminate;
 t.WaitFor;
 FreeAndNil(t);
 inherited Destroy;
end;

end.
4

1 に答える 1