线程怎么才能当定时器用呢?(100分)

  • 主题发起人 主题发起人 meng_1226
  • 开始时间 开始时间
M

meng_1226

Unregistered / Unconfirmed
GUEST, unregistred user!
线程怎么才能当定时器用呢?
有哪位高人做过这方面的程序
提点建议
 
去下一个AAFont,里面就有用线程做的定时器
 
嘿嘿,线程使用定时器是很多人都在问的问题了,在多线程版应该有的,另外你找深度历险来看看,上面有专门讲定时器的!
 
给你一个我写的单元 很好用的说




unit UntTMyTimer;

interface
uses SysUtils, Classes, windows, Contnrs;

type
TTimerMM = class;
SMyTimerDoKind = (SdkMainThread, SdkTimerThread);
TTimerItem = class
private
protected
Fkind: SMyTimerDoKind;
//名字
Fname: string;
//是否有效
FEnable: boolean;
//开始记时的时间
FStartTime: Cardinal;
//间隔的时间
FInvertTime: Cardinal;
//执行的次数 -1为永久执行
FTimerCount: Smallint;
//执行的事件
FOntimerEvent: TNotifyEvent;
//=============================
procedure SetEnable(Ivalue: boolean);
procedure SetinvertTime(Ivalue: Cardinal);
public
Parent: TTimerMM; //父组件
{执行类型 是主线程来执行 还是 定时线程自己执行}
property DoKind: SMyTimerDoKind read Fkind write Fkind;
property Enable: boolean read FEnable write SetEnable;
property InvertTime: Cardinal read FInvertTime write SetinvertTime;
property Ontimer: TNotifyEvent read FOntimerEvent write FOntimerEvent;
property Name: string read Fname;
{刷新记时}
procedure ReFresh;
{参数 间隔时间 执行事件 执行次数}
constructor Create(IInvertTime: Cardinal; IOntimerEvent: TNotifyEvent; IDoCount: Smallint = -1);
end;

TTimerMM = class(TThread)
private
Fid: Cardinal;
procedure SetCheckTime(const Value: Cardinal);
protected
FTepItem: TTimerItem;
FCheckTime: Cardinal;
FActiveList: TObjectList;
FFreeTimerList: TObjectList;
FNameList: TStringList; //名称列表
function GetDefaultName: string; //获取一个默认的名字
procedure Execute; override;
{检测事件}
procedure CheckOntimer;
{执行事件}
procedure DoOntimer;
{获取一个ID}
function GetAnId: Integer;
function GetTotCount: Cardinal;
public
{*检查的间隔时间}
property CheckTime: Cardinal read FCheckTime write SetCheckTime;
{总数}
property TotCount: Cardinal read GetTotCount;
{添加一个事件}
function AddAnOnTimer(IInvertTime: Cardinal; IOntimerEvent: TNotifyEvent;
IDoKInd: SMyTimerDoKind = SdkTimerThread; IName: string = ''; IDoCount:
Smallint = -1): TTimerItem;
function GetAnTimer(IName: string): TTimerItem;
function FreeAnTimer(IName: string): boolean;
constructor Create(CreateSuspended: Boolean = False; ICheckTimer: Cardinal = 100);
destructor Destroy; override;
end;

var
Gob_MyTimer: TTimerMM;

implementation
{ TTimerItem }

var
Gob_MyTimerItem: TTimerItem;
// Gob_MyTimer: TmyTimer;

constructor TTimerItem.Create(IInvertTime: Cardinal;
IOntimerEvent: TNotifyEvent; IDoCount: Smallint);
begin
FInvertTime := IInvertTime;
FTimerCount := IDoCount;
FOntimerEvent := IOntimerEvent;
FEnable := False;
end;

procedure TTimerItem.ReFresh;
begin
Enable := True;
end;

procedure TTimerItem.SetEnable(Ivalue: boolean);
begin
FEnable := Ivalue;
FStartTime := GetTickCount;
end;

procedure TTimerItem.SetinvertTime(Ivalue: Cardinal);
begin
Enable := False;
FInvertTime := Ivalue;
Enable := True;
end;

{ TmyTimer }

procedure TTimerMM.CheckOntimer;
var
I: Integer;
Ltep: TTimerItem;
begin
for I := FActiveList.Count - 1 downto 0 do begin // Iterate
if Terminated then
break;
try
Ltep := FActiveList.Items as TTimerItem;
if Ltep.Enable then begin
if GetTickCount >= Ltep.FStartTime + Ltep.InvertTime then begin
FTepItem := Ltep;
if FTepItem.DoKind = SdkMainThread then
Synchronize(DoOntimer)
else
DoOntimer;
if Ltep.FTimerCount <> -1 then
Dec(Ltep.FTimerCount);
Ltep.Enable := True;
if Ltep.FTimerCount = 0 then
FreeAnTimer(Ltep.Name);
end;
end;
except
end;
end; // for
end;

constructor TTimerMM.Create(CreateSuspended: Boolean = False; ICheckTimer:
Cardinal = 100);
begin
inherited Create(CreateSuspended);
FCheckTime := ICheckTimer;
FActiveList := TObjectList.Create;
FFreeTimerList := TObjectList.Create;
FNameList := TStringList.Create;
FreeOnTerminate := True;
Fid := 0;
end;

destructor TTimerMM.Destroy;
begin
try
FNameList.Free;
FFreeTimerList.Free;
FActiveList.Free;
except
end;
inherited;
end;

procedure TTimerMM.DoOntimer;
begin
FTepItem.Ontimer(FTepItem);
end;

procedure TTimerMM.Execute;
begin
while not Terminated do begin
CheckOntimer;
Sleep(FCheckTime);
end; // while
end;

function TTimerMM.FreeAnTimer(IName: string): boolean;
begin
Result := False;
Gob_MyTimerItem := GetAnTimer(IName);
if Gob_MyTimerItem <> nil then begin
Gob_MyTimerItem.Enable := False;
FFreeTimerList.Add(FActiveList.Extract(Gob_MyTimerItem));
FNameList.Delete(FNameList.IndexOf(IName));
Result := True;
end;
end;

function TTimerMM.GetAnId: Integer;
begin
Inc(Fid);
Result := Fid;
end;

function TTimerMM.GetDefaultName: string;
begin
Result := Format('%s%d', [Self.ClassName, GetAnId]);
end;

function TTimerMM.GetAnTimer(IName: string): TTimerItem;
var
Lidx: Integer;
begin
Lidx := FNameList.IndexOf(IName);
if Lidx > -1 then
Result := FNameList.Objects[Lidx] as TTimerItem
else
Result := nil;
end;

function TTimerMM.GetTotCount: Cardinal;
begin
Result := FActiveList.Count + FFreeTimerList.Count;
end;

function TTimerMM.AddAnOnTimer(IInvertTime: Cardinal; IOntimerEvent:
TNotifyEvent; IDoKInd: SMyTimerDoKind = SdkTimerThread; IName: string = '';
IDoCount: Smallint = -1): TTimerItem;
begin
if IName = '' then
IName := GetDefaultName;
if FNameList.IndexOf(IName) > -1 then
raise Exception.Create('名字重复了,创建失败');
//如果有空闲的 ITEM就拿来用
if FFreeTimerList.Count > 0 then begin
Gob_MyTimerItem := FFreeTimerList.Extract(FFreeTimerList.Items[0]) as TTimerItem;
Gob_MyTimerItem.InvertTime := IInvertTime;
Gob_MyTimerItem.Ontimer := IOntimerEvent;
Gob_MyTimerItem.FTimerCount := IDoCount;
Gob_MyTimerItem.Fname := IName;
Gob_MyTimerItem.DoKind := IDoKInd;
FActiveList.Add(Gob_MyTimerItem);
FNameList.AddObject(Gob_MyTimerItem.Name, Gob_MyTimerItem);
Gob_MyTimerItem.Enable := True;
end
else begin
Gob_MyTimerItem := TTimerItem.Create(IInvertTime, IOntimerEvent, IDoCount);
Gob_MyTimerItem.Fname := IName;
Gob_MyTimerItem.Parent := Self;
Gob_MyTimerItem.DoKind := IDoKInd;
FActiveList.Add(Gob_MyTimerItem);
FNameList.AddObject(Gob_MyTimerItem.Name, Gob_MyTimerItem);
Gob_MyTimerItem.Enable := True;
end;
Result := Gob_MyTimerItem;
end;

procedure TTimerMM.SetCheckTime(const Value: Cardinal);
begin
if Value < 10 then
raise Exception.Create('时间间隔设置过小!设置失败');
FCheckTime := Value;
end;

initialization
Gob_MyTimer := TTimerMM.Create();
finalization
try
Gob_MyTimer.Terminate;
except
end;

end.
 
使用的时候很简单
申明一个过程 比如
procedure DoTimeGetMisson(Sender: TObject);

只要是这个参数就可以了过程需要是类方法(申明在类里边)
Gob_MyTimer.AddAnOnTimer(1000, DoTimeGetMisson);
这样添加进去就OK 每秒执行一次
你还可以像控制定时器一样控制每个TTimerItem 的可用 刷新 和执行多少次后停止
 
实现的方法挺多的,
1、用线程加载timer控件
2、使用事件等待
3、api定时函数
 
使用GetTickCount函数就可以了。
技术交流QQ:136293586
 
接受答案了.
 
后退
顶部