Delphi--长线程

{
  长线程,
  开启:随应用程序启用而启动
  关闭:岁应用程序关闭而结束
}
unit uLongThread;

interface

uses
  Classes, ADODB, DB, ActiveX, SysUtils;

type
  //线程状态,空闲、繁忙、异常、外部终止
  TThreadStatus = (tsIdle, tsBusy, tsException, tsTerminate);

type
  TLongThread = class(TThread)
  private
    FState: TThreadStatus;
    FSleepTimes: Integer;


    {************************************分割线,上面是变量定义,下面是方法集合********************************************}
    //线程休眠
    function SetThreadSleep(aInterval: Integer): Boolean;
    //线程创建时初始化
    procedure InitOnCreate(aConn: TADOConnection; aSleepTimes: Integer);
    //线程结束时销毁对象
    procedure DoOnDestroy;
    //线程实际执行体
    procedure Executed;

    {************************************分割线,上面是公用方法,下面是具体的业务代码********************************************}

  protected
    procedure Execute; override;
  public
    constructor Create(aConn: TADOConnection; aSleepTimes: Integer = 180);
    destructor Destroy; override;
  published
    //线程状态
    property ThreadStatus: TThreadStatus read FState write FState;
    //线程定时间隔时间,即休眠时间
    property ThreadSleepTimes: Integer read FSleepTimes write FSleepTimes;
  end;

implementation

{ TLongThread }

constructor TLongThread.Create(aConn: TADOConnection; aSleepTimes: Integer);
begin
  InitOnCreate(aConn, aSleepTimes);
  inherited Create(False);
end;

destructor TLongThread.Destroy;
begin
  DoOnDestroy;
  inherited;
end;

procedure TLongThread.DoOnDestroy;
begin

end;

procedure TLongThread.Execute;
begin
  //延时一点时间执行,先让主窗体显示出来
  SetThreadSleep(10);

  CoInitialize(nil);
  try
    while not Terminated do
    begin
      FState := tsBusy;
      //核心方法
      Executed;

      //保证CPU释放
      Sleep(10);
      //下面这一句判断十分有必要,如果上面执行体运行很久,期间外部中止线程。
      //缺少这一句控制,会在执行体结束后立即进入休眠期,这样外部控制此时无效。有漏洞
      if FState = tsTerminate then
      begin
        Self.Terminate;
        Break;
      end;

      //线程进入休眠期,等待下一次唤醒
      FState := tsIdle;
      if not SetThreadSleep(FSleepTimes) then
      begin
        Self.Terminate;
        Break;
      end;
    end;
  finally
    CoUninitialize;
  end;
end;

procedure TLongThread.Executed;
begin

end;

procedure TLongThread.InitOnCreate(aConn: TADOConnection; aSleepTimes: Integer);
begin
  FSleepTimes := aSleepTimes;
  //默认空闲
  FState := tsIdle;


end;

function TLongThread.SetThreadSleep(aInterval: Integer): Boolean;
var
  SlpTicket: Cardinal;
  n: Integer;
begin
  Result := True;
  //直接间隔N秒,不考虑线程执行体中的函数执行时间
  SlpTicket := aInterval * 1000;
  n := SlpTicket div 100; //每100毫秒执行一次循环
  while n > 0 do
  begin
    Sleep(100);
    Dec(n);
    if FState = tsTerminate then
    begin
      Result := False;
      Exit;
    end;
  end;
end;

end.

调用方法

//创建线程
  if not Assigned(fLongThread) then
  begin
    fLongThread := TLongThread.Create(ADOConnection1, 240);
    //do something
  end;

销毁线程

  //结束线程
  if Assigned(fLongThread) then
  begin
    fLongThread.ThreadStatus := tsTerminate;
    fLongThread.WaitFor;
    FreeAndNil(fLongThread);
  end;

长线程,      开启:随应用程序启用而启动      关闭:岁应用程序关闭而结束  应用场景:      一般用于后台长期开启,我个人的主要用途是做上传下载。

猜你喜欢

转载自www.cnblogs.com/wangxiaoxiao77/p/12058106.html