您的位置:首页 > 编程语言 > Delphi

DELPHI基于线程的定时器和一个泛型对象池

2016-05-12 01:13 801 查看
笔记

unit ThreadTimer;

//次编译指令仅在测试时使用,请勿在Release版本中打开
{$DEFINE RunInMainThread}

interface
uses
SysUtils, Classes, SyncObjs;
type
TThreadTimer = class(TObject)
private
FEnabled: Boolean;
FWaitEvent: TEvent;
FOnTimer: TNotifyEvent;
FInterval: Integer;
FWorkThread: TThread;
procedure SetEnabled(const Value: Boolean);
procedure DoInterval;
procedure DoTimer;
procedure StartTimer;
procedure StopTimer;
public
constructor Create;
destructor Destroy; override;
property Enabled: Boolean read FEnabled write SetEnabled;
property Interval: Integer read FInterval write FInterval;
property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
end;

TWorkThread = class(TThread)
private
FOwner: TThreadTimer;
procedure DoTimer;
protected
procedure Execute; override;
public
constructor Create(AOwner: TThreadTimer);
end;

implementation

{ TThreadTimer }

constructor TThreadTimer.Create;
begin
inherited Create;
FInterval := 1000;
FWaitEvent := TEvent.Create(nil, False, False, '');
FWorkThread := nil;
end;

destructor TThreadTimer.Destroy;
begin
StopTimer;
FreeAndNil(FWaitEvent);
inherited;
end;

procedure TThreadTimer.DoInterval;
begin
FWaitEvent.WaitFor(FInterval);
end;

procedure TThreadTimer.DoTimer;
begin
if Assigned(FOnTimer) then
FOnTimer(Self);
end;

procedure TThreadTimer.SetEnabled(const Value: Boolean);
begin
if FEnabled <> Value then
begin
if Value then
StartTimer
else
StopTimer;
FEnabled := Value;
end;
end;

procedure TThreadTimer.StartTimer;
begin
if FWorkThread = nil then
begin
FWorkThread := TWorkThread.Create(Self);
FWaitEvent.ResetEvent;
FWorkThread.Start;
end;
end;

procedure TThreadTimer.StopTimer;
begin
if FWorkThread <> nil then
begin
FWorkThread.Terminate;
//设置信号
FWaitEvent.SetEvent;
//等待结束
FWorkThread.WaitFor;
FreeAndNil(FWorkThread);
end;
end;

{ TWorkThread }

constructor TWorkThread.Create(AOwner: TThreadTimer);
begin
inherited Create(True);
FOwner := AOwner;
end;

procedure TWorkThread.DoTimer;
begin
FOwner.DoTimer;
end;

procedure TWorkThread.Execute;
begin
while not Self.Terminated do
begin
FOwner.DoInterval;
if not Self.Terminated then
begin
{$IFDEF RunInMainThread}
Synchronize(Self.DoTimer);
{$ELSE}
FOwner.DoTimer;
{$ENDIF}
end;
end;
end;

end.


泛型对象池

unit ObjectPool;

interface
uses
Classes, SyncObjs, SysUtils, Generics.Collections,
ThreadTimer;
type
TObjectPool<T> = class
private
FCacheList: TThreadList<T>;
FTimer: TThreadTimer;
FMaxPoolSize: Cardinal;
FMinPoolSize: Cardinal;
procedure InitObjectPool(const APoolSize: Cardinal);
public
constructor Create(AObject: T; AMaxPoolSize: Cardinal = 5; AMinPoolSize: Cardinal = 3);
destructor Destroy; override;
property MaxPoolSize: Cardinal read FMaxPoolSize write FMaxPoolSize;
property MinPoolSize: Cardinal read FMinPoolSize write FMinPoolSize;
end;
implementation

{ TObjectPool<T> }

constructor TObjectPool<T>.Create(AObject: T; AMaxPoolSize,
AMinPoolSize: Cardinal);
begin
FCacheList := TThreadList<T>.Create;
FTimer := TThreadTimer.Create;
FTimer.Interval := 30000; //30秒检查一次
FMaxPoolSize := AMaxPoolSize;
FMinPoolSize := AMinPoolSize;
InitObjectPool(AMinPoolSize);
end;

destructor TObjectPool<T>.Destroy;
var
I: Integer;
LockList: TList<T>;
begin
if Assigned(FCacheList) then
begin
LockList := FCacheList.LockList;
try
for I := 0 to LockList.Count - 1 do
FreeAndNil(LockList.Items[I]);
finally
FCacheList.UnlockList;
FCacheList.Free;
end;
end;
FTimer.Free;
inherited;
end;

procedure TObjectPool<T>.InitObjectPool(const APoolSize: Cardinal);
begin

end;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: