Multithreading 线程销毁永远不会执行

Multithreading 线程销毁永远不会执行,multithreading,delphi,memory-leaks,delphi-7,Multithreading,Delphi,Memory Leaks,Delphi 7,下载带有已编译可执行文件(221KB(226925字节))的源代码: 如果在线程终止之前关闭应用程序(单击X按钮),为什么不调用销毁析构函数?FastMM4报告内存泄漏和FPauseEvent事件 我应该如何销毁线程?如果有人在线程完成之前关闭应用程序 unit SkeletonThread; interface uses Windows, Classes, SysUtils, SyncObjs; type TOnInitialize = procedure(Sender: TOb

下载带有已编译可执行文件(221KB(226925字节))的源代码:

如果在线程终止之前关闭应用程序(单击X按钮),为什么不调用销毁析构函数?FastMM4报告内存泄漏和FPauseEvent事件

我应该如何销毁线程?如果有人在线程完成之前关闭应用程序

unit SkeletonThread;

interface

uses
  Windows, Classes, SysUtils, SyncObjs;

type
  TOnInitialize = procedure(Sender: TObject; const AMaxValue: Integer) of object;
  TOnBegin = procedure(Sender: TObject) of object;
  TOnProgress = procedure(Sender: TObject; const APosition: Integer) of object;
  TOnPause = procedure(Sender: TObject; const APaused: Boolean) of object;
  TOnFinish = procedure(Sender: TObject) of object;
  TOnFinalize = procedure(Sender: TObject) of object;

  TMasterThread = class(TThread)
  private
    { Private declarations }
    FPaused: Boolean;
    FPosition: Integer;
    FMaxValue: Integer;
    FOnBegin: TOnBegin;
    FOnProgress: TOnProgress;
    FOnFinish: TOnFinish;
    FOnInitialize: TOnInitialize;
    FOnFinalize: TOnFinalize;
    FPauseEvent: TEvent;
    FOnPause: TOnPause;
    procedure BeginEvent();
    procedure ProgressEvent();
    procedure FinishEvent();
    procedure InitializeEvent();
    procedure FinalizeEvent();
    procedure PauseEvent();
    procedure CheckForPause();
  protected
    { Protected declarations }
    procedure DoInitializeEvent(const AMaxValue: Integer); virtual;
    procedure DoBeginEvent(); virtual;
    procedure DoProgress(const APosition: Integer); virtual;
    procedure DoPauseEvent(const APaused: Boolean); virtual;
    procedure DoFinishEvent(); virtual;
    procedure DoFinalizeEvent(); virtual;
  public
    { Public declarations }
    constructor Create(const CreateSuspended: Boolean; const theValue: Integer);
    destructor Destroy(); override;
    procedure Pause();
    procedure Unpause();
  published
    { Published declarations }
    property IsPaused: Boolean read FPaused write FPaused default False;
    property OnInitialize: TOnInitialize read FOnInitialize write FOnInitialize default nil;
    property OnBegin: TOnBegin read FOnBegin write FOnBegin default nil;
    property OnProgress: TOnProgress read FOnProgress write FOnProgress default nil;
    property OnPause: TOnPause read FOnPause write FOnPause default nil;
    property OnFinish: TOnFinish read FOnFinish write FOnFinish default nil;
    property OnFinalize: TOnFinalize read FOnFinalize write FOnFinalize default nil;
  end;

  TSkeletonThread = class(TMasterThread)
  private
    { Private declarations }
    procedure DoExecute(const theValue: Integer);
  protected
    { Protected declarations }
    procedure Execute(); override;
  public
    { Public declarations }
  published
    { Published declarations }
  end;

implementation

{ TMasterThread }
constructor TMasterThread.Create(const CreateSuspended: Boolean; const theValue: Integer);
begin
  inherited Create(CreateSuspended);
  Self.FreeOnTerminate := True;

  Self.FPosition := 0;
  Self.FMaxValue := theValue;
  Self.FPaused := False;
  Self.FPauseEvent := TEvent.Create(nil, True, True, '');
end;

destructor TMasterThread.Destroy();
begin
  FreeAndNil(FPauseEvent);
  if (Pointer(FPauseEvent) <> nil) then Pointer(FPauseEvent) := nil;
  inherited Destroy();
end;

procedure TMasterThread.DoBeginEvent();
begin
  if Assigned(Self.FOnBegin) then Self.FOnBegin(Self);
end;

procedure TMasterThread.BeginEvent();
begin
  Self.DoBeginEvent();
end;

procedure TMasterThread.DoProgress(const APosition: Integer);
begin
  if Assigned(Self.FOnProgress) then Self.FOnProgress(Self, APosition);
end;

procedure TMasterThread.ProgressEvent();
begin
  Self.DoProgress(Self.FPosition);
end;

procedure TMasterThread.DoFinishEvent();
begin
  if Assigned(Self.FOnFinish) then Self.FOnFinish(Self);
end;

procedure TMasterThread.FinishEvent();
begin
  Self.DoFinishEvent();
end;

procedure TMasterThread.DoInitializeEvent(const AMaxValue: Integer);
begin
  if Assigned(Self.FOnInitialize) then Self.FOnInitialize(Self, AMaxValue);
end;

procedure TMasterThread.InitializeEvent();
begin
  Self.DoInitializeEvent(Self.FMaxValue);
end;

procedure TMasterThread.DoFinalizeEvent();
begin
  if Assigned(Self.FOnFinalize) then Self.FOnFinalize(Self);
end;

procedure TMasterThread.FinalizeEvent;
begin
  Self.DoFinalizeEvent();
end;

procedure TMasterThread.DoPauseEvent(const APaused: Boolean);
begin
  if Assigned(Self.FOnPause) then Self.FOnPause(Self, APaused);
end;

procedure TMasterThread.PauseEvent();
begin
  Self.DoPauseEvent(Self.FPaused);
end;

procedure TMasterThread.Pause();
begin
  Self.FPauseEvent.ResetEvent();
  Self.FPaused := True;
  Self.Synchronize(Self.PauseEvent);
end;

procedure TMasterThread.Unpause();
begin
  Self.FPaused := False;
  Self.Synchronize(Self.PauseEvent);
  Self.FPauseEvent.SetEvent();
end;

procedure TMasterThread.CheckForPause();
begin
  if (not (Self.Terminated)) then Windows.Sleep(1);
  Self.FPauseEvent.WaitFor(INFINITE);
end;

{ TSkeletonThread }
procedure TSkeletonThread.DoExecute(const theValue: Integer);
var
  X: Integer;
begin
  Self.Synchronize(InitializeEvent);
  try
    Self.Synchronize(BeginEvent);
    try
      for X := 0 to (theValue - 1) do
      begin
    Self.CheckForPause();

    if (not Self.FPaused) and (not Self.Terminated) then
    begin
      Self.FPosition := Self.FPosition + 1;
      Self.Synchronize(ProgressEvent);
    end
    else begin
      Break;
    end;
      end;

      for X := Self.FPosition downto 1 do
      begin
    Self.CheckForPause();

    if (not Self.FPaused) and (not Self.Terminated) then
    begin
      Self.FPosition := X;
      Self.Synchronize(ProgressEvent);
    end
    else begin
      Break;
    end;
      end;
    finally
      Self.Synchronize(FinishEvent);
    end;
  finally
    Self.Synchronize(FinalizeEvent);
  end;
end;

procedure TSkeletonThread.Execute();
begin
  Self.DoExecute(Self.FMaxValue);
end;

end.
单位骨架;
接口
使用
Windows、类、SysUtils、SyncObjs;
类型
TOnInitialize=对象的过程(发送方:TObject;常量AMaxValue:Integer);
TOnBegin=对象的过程(发送方:TObject);
TOnProgress=对象的过程(发送方:ToObject;常量:Integer);
TOnPause=对象的过程(发送方:TObject;常量:Boolean);
TOnFinish=对象的过程(发送方:TObject);
TONFalize=对象的过程(发送方:TObject);
TMasterThread=class(TThread)
私有的
{私有声明}
FPaused:布尔型;
FPosition:整数;
FMaxValue:整数;
丰贝京:托贝京;
FOnProgress:TOnProgress;
粉饰:粉饰;
FOnInitialize:TOnInitialize;
Fonfalize:TOnFinalize;
FPauseEvent:TEvent;
FOnPause:TOnPause;
程序BeginEvent();
过程ProgressEvent();
程序FinishEvent();
过程初始化事件();
程序FinalizeEvent();
程序PauseEvent();
过程检查暂停();
受保护的
{受保护的声明}
过程DoInitializeEvent(常量AMaxValue:整数);事实上的
程序dobeginvent();事实上的
过程DoProgress(常数:整数);事实上的
过程DoPauseEvent(常量:布尔值);事实上的
程序DoFinishEvent();事实上的
过程DoFinalizeEvent();事实上的
公众的
{公开声明}
构造函数Create(constcreatesuspended:Boolean;constthevalue:Integer);
析构函数Destroy();推翻
程序暂停();
程序取消暂停();
出版
{已发布声明}
属性IsPaused:Boolean read FPaused write FPaused default False;
属性OnInitialize:TOnInitialize read FOnInitialize write FOnInitialize default nil;
属性OnBegin:TOnBegin read FOnBegin write FOnBegin default nil;
属性OnProgress:TOnProgress read-FOnProgress-write-FOnProgress-default-nil;
属性OnPause:TOnPause read FOnPause write FOnPause default nil;
属性OnFinish:TOnFinish read FOnFinish write FOnFinish默认为零;
属性OnFinalize:TOnFinalize read FOnFinalize write FOnFinalize默认为零;
结束;
TSkeletonThread=类(TMasterThread)
私有的
{私有声明}
过程执行(常量值:整数);
受保护的
{受保护的声明}
过程执行();推翻
公众的
{公开声明}
出版
{已发布声明}
结束;
实施
{TMasterThread}
构造函数TMasterThread.Create(constcreatesuspended:Boolean;constthevalue:Integer);
开始
继承的创建(CreateSuspended);
Self.FreeOnTerminate:=真;
Self.FPosition:=0;
Self.FMaxValue:=该值;
Self.FPaused:=假;
Self.FPauseEvent:=TEvent.Create(nil,True,True,”);
结束;
析构函数TMasterThread.Destroy();
开始
免费和无(FPauseEvent);
如果(指针(FPauseEvent)为nil),则指针(FPauseEvent):=nil;
继承销毁();
结束;
过程TMasterThread.DoBeginEvent();
开始
如果已分配(Self.FOnBegin),则为Self.FOnBegin(Self);
结束;
过程TMasterThread.BeginEvent();
开始
Self.dobeginvent();
结束;
过程TMasterThread.DoProgress(常量:整数);
开始
如果分配了(Self.FOnProgress),那么Self.FOnProgress(Self,APosition);
结束;
过程TMasterThread.ProgressEvent();
开始
自DoProgress(Self.FPosition);
结束;
过程TMasterThread.DoFinishEvent();
开始
如果已分配(Self.FOnFinish),则为Self.FOnFinish(Self);
结束;
程序TMasterThread.FinishEvent();
开始
Self.DoFinishEvent();
结束;
过程TMasterThread.DoInitializeEvent(常量AMaxValue:Integer);
开始
如果已分配(Self.FOnInitialize),则Self.FOnInitialize(Self,AMaxValue);
结束;
过程TMasterThread.InitializeEvent();
开始
Self.DoInitializeEvent(Self.FMaxValue);
结束;
过程TMasterThread.DoFinalizeEvent();
开始
如果已分配(Self.FOnFinalize),则Self.FOnFinalize(Self);
结束;
程序TMasterThread.FinalizeEvent;
开始
Self.DoFinalizeEvent();
结束;
过程TMasterThread.DoPauseEvent(const:Boolean);
开始
如果已分配(Self.FOnPause),则Self.FOnPause(Self,apause);
结束;
过程TMasterThread.PauseEvent();
开始
Self.DoPauseEvent(Self.FPaused);
结束;
过程TMasterThread.Pause();
开始
Self.FPauseEvent.ResetEvent();
Self.FPaused:=真;
自同步(Self.PauseEvent);
结束;
过程TMasterThread.unpuse();
开始
Self.FPaused:=假;
自同步(Self.PauseEvent);
Self.FPauseEvent.SetEvent();
结束;
过程TMasterThread.CheckForPause();
开始
如果为(非(自终止)),则为Windows.Sleep(1);
Self.FPauseEvent.WaitFor(无限);
结束;
{TSkeletonThread}
过程TSkeletonThread.DoExecute(常量值:整数);
变量
X:整数;
开始
自同步(初始化事件);
尝试
自同步(BeginEvent);
尝试
对于X:=0到(值-1)do
开始
Self.CheckForPause();
如果(非自终止)和(非自终止),则
开始
Self.FPosition:=Self.FPosition+1;
自同步(ProgressEvent);
结束
否则开始
打破
结束;
结束;
对于X:=Self.FPosition downto 1 do
开始
Self.CheckForPause();
如果(非自终止)和(非自终止),则
开始
自我定位:=X;
自同步(ProgressEvent);
结束
否则开始
打破
结束;
结束;
最后
自同步(FinishEvent);
结束;
最后
自同步(FinalizeEvent);
结束;
结束;
过程TSkeletonThread.Execute();
开始
Self.DoExecute(Self.FMa
procedure Execute;
begin
  inherited;

  while not Terminated do
  begin
    // do your job
  end;
end;

procedure TForm1.StopThread;
begin
  MyThread.Terminate;

  // wait and block until the scheduling thread is finished
  AResult := WaitForSingleObject(MyThread.Handle, cShutdownTimeout);

  // check if we timed out
  if AResult = WAIT_TIMEOUT then
    TerminateThread(MyThread.Handle, 0);
end;
procedure Execute;
begin
  inherited;

  while not Terminated do
  begin
    WaitStatus := WaitForSingleObject(FTermEvent, Max(0, SleepInterval));

    // check what was the cause for signalization
    if WaitStatus <> WAIT_TIMEOUT then
      Terminate;
  end;
end;

procedure TForm1.StopThread;
begin
  // Terminate the thread
  SetEvent(FTermEvent);
  // close the handle
  CloseHandle(FTermEvent);

  // wait and block until the scheduling thread is finished
  AResult := WaitForSingleObject(MyThread.Handle, cShutdownTimeout);

  // check if we timed out
  if AResult = WAIT_TIMEOUT then
    TerminateThread(MyThread.Handle, 0);
end;