怎样在线程中实现timer(30分)

D

djw777

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在线程中实现Ttimer的不断执行
 
用多媒体定时器或者用WaitForSingleObject伪造一个也可以
 
timer本身也是一个线程
 
Timer不是一个线程,呵呵,他是窗口消息队列的一部分
 
如果没记错的话,WWW.51DELPHI.COM就有这样的控件,利用线程
来达到定时器的目的。
 
to张无忌:那个时间消息是如何产生的?
 
unit ThdTimer;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;
type
TThreadedTimer = class;
TTimerThread = class(TThread)
OwnerTimer: TThreadedTimer;
procedure Execute;
override;
end;

TThreadedTimer = class(TComponent)
private
FEnabled: Boolean;
FInterval: DWord;
FOnTimer: TNotifyEvent;
FTimerThread: TTimerThread;
protected
procedure Timer;
dynamic;
public
constructor Create(AOwner: TComponent);
override;
destructor Destroy;
override;
published
property Enabled: Boolean
read FEnabled write FEnabled default True;
property Interval: DWord
read FInterval write FInterval default 1000;
property OnTimer: TNotifyEvent
read FOnTimer write FOnTimer;
end;

procedure Register;
implementation
procedure TTimerThread.Execute;
var
dwTick: DWord;
iTick: Integer;
begin
Priority := tpNormal;
//tpTimeCritical;
repeat
dwTick := GetTickCount();
//Synchronize(OwnerTimer.Timer);
OwnerTimer.Timer;
iTick := OwnerTimer.FInterval - (GetTickCount() - dwTick);
if iTick < 0 then
iTick := 0;
Sleep(iTick);
until Terminated;
end;

constructor TThreadedTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := False;
FInterval := 1000;
FTimerThread := TTimerThread.Create(False);
FTimerThread.OwnerTimer := Self;
end;

destructor TThreadedTimer.Destroy;
begin
with FTimerThreaddo
begin
Terminate;
WaitFor;
Free;
end;
inherited Destroy;
end;

procedure TThreadedTimer.Timer;
begin
if FEnabled and Assigned(FOnTimer) then
FOnTimer(Self);
end;

procedure Register;
begin
RegisterComponents('Samples', [TThreadedTimer]);
end;

end.

我有这个代码,但我看不明白,一起研究一下吧
 
procedure TTimerThread.Execute;
var
dwTick: DWord;
iTick: Integer;
begin
Priority := tpNormal;
//tpTimeCritical;
// 上面这句是线程优先级
repeat
dwTick := GetTickCount();
// 获得TickCount
//Synchronize(OwnerTimer.Timer);
OwnerTimer.Timer;
// 调用自定义的OnTimer事件
iTick := OwnerTimer.FInterval - (GetTickCount() - dwTick);
// GetTickCount() - dwTick获得前面几句的执行时间,用Interval减去这些时间,
// 得出结果如果小于0,则说明已经过去了Interval时间,然后置0。
if iTick < 0 then
iTick := 0;
Sleep(iTick);
// 休眠iTick时间
until Terminated;
end;
 
在线程里实现Timer没有必要,因为线程就可以达到定时的功能,你可以在Execute里面执行
完需要的操作以后,Sleep(Interval)一下就可以了,但这样的执行时间就会大于Interval,
如果想要精确一些,则就像上面的写法一样用GetTickCount获得操作代码的执行时间,
并在Interval里减去操作代码的执行时间,判断差值,如果小于0,则置为0,如果大于0则
Sleep(差值),这样repeat里的代码执行一次最少是Interval时间,最多等于操作代码的执
行时间加上其余代码的执行时间。
如果有疑问,请继续提出。
 
同意楼上,在线程里想实现类TIMER的东西,用waitFor类的函数就搞定,
或者用多媒体定时器,哈,那更精确,TTimer太不精确了,而且时钟
消息是优先级最低的消息,很容易丢失。。。
 
while truedo
begin

do.....
sleep(2000);
end;
 
时钟消息是优先级最低的消息//????????????
,很容易丢失
 
确实如此!还有WM_PAINT消息也是优先级很低的消息之一!
 
多媒体定时器是什么东西,我怎么没找到,这几天正要做这样的一个线程,多谢各位指点啊!
 
我利用上面的代码,
我只要将我要执行的代码写到time.timer事件中就可以吗?
我在主程序中应该在什么地方写?是在ONcreate 还是在主窗体 显示时候写onshow
 
只要将我要执行的代码写到time.timer事件中就可以了,
当然是在OnCreate里写啦
 
尚未调用coinitialize是什么错误?
 
多媒体定时器,在哪项里阿
 
顶部