时间轮算法的定时器,Delphi

源码下载 https://files.cnblogs.com/lwm8246/uTimeWheel.rar

D7,XE2 编译测试OK

  1 //时间轮算法的定时器
  2 //2014-02-23 14:54 QQ 287413288
  3 
  4 unit uTimeWheel;
  5 
  6 interface
  7 
  8 uses
  9   Windows,Classes,SysUtils,SyncObjs;
 10 
 11 type
 12   PTWItem=^TTWItem;
 13   TTWItem=record
 14     UserData:Pointer; //用户数据
 15     Tag:Integer;      //用户数据
 16     Positin:Integer;
 17     Interval:Integer;//定时时间(ms)
 18   end;
 19 
 20   TTimeWheel=class(TThread)
 21   private
 22     FCS:TCriticalSection;
 23     FInterval:Integer;
 24     FWorkDone:Boolean;
 25     function getPosition: Integer;
 26   protected
 27     FPosition:Integer;
 28     FSize:DWORD;
 29     FList:TList;
 30     procedure Execute();override;
 31     procedure OnTime(PI:PTWItem);virtual;abstract;
 32   public
 33     //AOnTimeCount 最大触发次数
 34     constructor Create(AOnTimeCount:DWORD;AInterval:Integer);virtual;
 35     destructor  Destroy();override;
 36     procedure   Lock();
 37     procedure   UnLock();
 38     procedure   Start();
 39     procedure   Stop();
 40     //\\
 41     function   RegisterTime(AInterval:Integer):PTWItem;virtual;
 42   public
 43     property List:TList read FList;
 44     property Position:Integer read getPosition;
 45     property Interval:Integer  read FInterval; //单位 ms
 46     property WorkDone:Boolean read FWorkDone;
 47   end;
 48 
 49 implementation
 50 
 51 { TTimeWheel }
 52 
 53 constructor TTimeWheel.Create(AOnTimeCount:DWORD;AInterval:Integer);
 54 var
 55   Index:DWORD;
 56   PI:PTWItem;
 57 begin
 58   inherited Create(TRUE);
 59   FCS := TCriticalSection.Create();
 60   FLIst := TList.Create();
 61   FList.Capacity := AOnTimeCount;
 62   FSize     := AOnTimeCount;
 63   FInterval := AInterval;
 64   for Index := 0 to FSize - 1 do
 65   begin
 66     New(PI);
 67     PI^.UserData  := nil;
 68     PI^.Interval  := 0;
 69     FList.Add(PI);
 70   end;
 71   FPosition := 0;
 72   FreeOnTerminate := FALSE;
 73   FWorkDone := FALSE;
 74 end;
 75 
 76 destructor TTimeWheel.Destroy;
 77 var
 78   Index:integer;
 79   PI:PTWItem;
 80 begin
 81   FCS.Free();
 82   for Index := 0 to FList.Count - 1 do
 83   begin
 84     PI := PTWItem(FList.Items[Index]);
 85     if PI <> nil then Dispose(PI);
 86   end;
 87   FList.Free();
 88   inherited;
 89 end;
 90 
 91 procedure TTimeWheel.Execute;
 92   procedure Delay(Value:Integer);
 93   begin
 94     while((not Terminated) and (Value > 0)) do
 95     begin
 96       Dec(Value,100);
 97       Sleep(100);
 98     end;
 99   end;
100 var
101   PI:PTWItem;
102 begin
103   while(not Terminated) do
104   begin
105     //Sleep(FInterval);
106     Delay(FInterval);
107     Lock();
108     try
109       Inc(FPosition);
110       FPosition := FPosition mod FSize;
111       PI := FList.Items[FPosition];
112       PI^.Positin := FPosition;
113     finally
114       UnLock();
115     end;
116     //触发时间到事件
117     if not Terminated then
118     begin
119       OnTime(PI);
120     end;
121   end;
122   FWorkDone := TRUE;
123 end;
124 
125 function TTimeWheel.getPosition: Integer;
126 begin
127   FCS.Enter();
128   Result := FPosition;
129   FCS.Leave();
130 end;
131 
132 procedure TTimeWheel.Lock;
133 begin
134   FCS.Enter();
135 end;
136 
137 function TTimeWheel.RegisterTime(AInterval: Integer): PTWItem;
138 var
139   Lfactor:Integer;
140   LPosition:Integer;
141 begin
142   if AInterVal > FInterval * FSize then
143     raise exception.CreateFmt('TTimeWheel.RegisterTime(%d),Out of Time Range',[AInterval]);
144   Lfactor   := AInterval div FInterval;
145   LPosition := Position + Lfactor;
146   LPosition := LPosition mod FSize;
147   Result    := FList.Items[LPosition];
148   Result^.Interval := AInterval;
149   Result^.Positin  := LPosition;
150 end;
151 
152 procedure TTimeWheel.Start();
153 begin
154   Resume();
155 end;
156 
157 procedure TTimeWheel.Stop;
158 begin
159   Terminate();
160   while(TRUE) do
161   begin
162     if FWorkDone then Break;
163     Sleep(100);
164   end;
165 end;
166 
167 procedure TTimeWheel.UnLock;
168 begin
169   FCS.Leave();
170 end;
171 
172 
173 end.