{ 长线程, 开启:随应用程序启用而启动 关闭:岁应用程序关闭而结束 } 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;
长线程, 开启:随应用程序启用而启动 关闭:岁应用程序关闭而结束 应用场景: 一般用于后台长期开启,我个人的主要用途是做上传下载。