6

ここで尋ねるように、私はマルチスレッドアプリケーションを持っています。スレッドを終了し、次のメソッドが呼び出されたときに新しいスレッドを開始したい。

procedure TFRABData.RefreshDataset;
var
  GridUpdater: TGridUpdater;
begin
  if Assigned(updaterThread) and (updaterThread <> nil) then
  begin
    updaterThread.Terminate;
  end;
  GridUpdater := TGridUpdater.Create(True);
  GridUpdater.OwnerForm := Self;
  updaterThread := GridUpdater;
  GridUpdater.FreeOnTerminate := False;
  GridUpdater.Start;
  CodeSite.Send('RefreshDataset executed');
end

しかし、にFreeOnTerminate設定するTrueとアクセス違反が発生しますが、にFreeOnTerminate設定するFalseとメモリリークが発生します。スレッドを解放するには?

4

3 に答える 3

10

Terminate()WaitFor()およびFree()すべてを一緒に呼び出す必要があります。たとえば、次のようになります。

procedure TFRABData.RefreshDataset; 
var 
  GridUpdater: TGridUpdater; 
begin 
  if Assigned(updaterThread) then 
  begin 
    updaterThread.Terminate; 
    updaterThread.WaitFor; 
    FreeAndNil(updaterThread); 
  end; 
  GridUpdater := TGridUpdater.Create(True); 
  GridUpdater.OwnerForm := Self; 
  GridUpdater.Start; 
  updaterThread := GridUpdater; 
  CodeSite.Send('RefreshDataset executed'); 
end;
于 2012-09-25T17:52:21.890 に答える
8

そして、RRUZの答えに加えて、それを動作させるにはFreeOnTerminate = False

Terminateフラグを設定するだけで、それ以上は何もしません。

変化する

  if Assigned(updaterThread) and (updaterThread <> nil) then 
  begin 
    updaterThread.Terminate; 
  end; 

  if Assigned(updaterThread) then 
  begin 
    updaterThread.Free; 
  end; 

Freeその後、メモリリークを解消するためTerminateに呼び出します。WaitFor

于 2012-09-25T06:24:15.683 に答える
6
  1. 中断されたスレッドを開始する必要はありません
  2. TThreadOwnerFormパラメーターを受け取るようにコンストラクターを変更します
  3. スレッドのコンストラクターでFreeOnTerminate値を設定します。
  4. 中断されていない状態でTThreadを開始します。

そういうもの。

  TGridUpdater = class(TThread)
  private
    FOwnerForm: TForm;
  public
    constructor Create(OwnerForm : TForm); overload;
    destructor Destroy; override;
    procedure Execute; override;
  end;

constructor TGridUpdater.Create(OwnerForm: TForm);
begin
  inherited Create(False);
  FreeOnTerminate := True;
  FOwnerForm:=OwnerForm;
end;

destructor TGridUpdater.Destroy;
begin

  inherited;
end;

procedure TGridUpdater.Execute;
begin
  //your code goes here

end;

これで、この方法でTthreadを作成できます

GridUpdater:=TGridUpdater.Create(Self); //Just set it and forget it
于 2012-09-25T06:11:22.777 に答える