有关Timer的问题 - 不爽(300分)

T

Town

Unregistered / Unconfirmed
GUEST, unregistred user!
1. 是否有人用过MMTools的HiTimer? 在98下,定时超过1分钟就不准了, 比如定时3分钟,
结果40秒就触发了。而在2K下就没问题。 Why?

2. 两个Timer会互相干扰么?如何解决? 用两个多线程的Timer(比如深度历险当的)呢?

3. 据说,当消息队列太多忙不过来的时候, Timer会丢掉反应,下一次才触发。 那么
多线程的Timer是不是也会遇到这样的问题呢? 有办法解决么?

4. 我在深度历险当了个多线程的Timer,分析了一下源码,它是在线程中调用的Sleep
函数。我觉得精度不高,所以用GetTickCount循环编的Delay函数替代了Sleep. 结果
狂吃CPU。 谁有精度高一些, 不太吃CPU的多线程Timer给俺用用。 谢了!
 
自己用API写一个定时的。
 
gettickcount
 
多每体定时器或者用2K的时间线程池
 
呵呵, 我有4个问题啊~~ 用哪个API啊? 是用Queryperformancecounter...
么? 好像也很吃CPU啊~
 
To 张无忌:
多媒体定时器? 不就是TimeGetTime或者GetTickCount么? 我用他们在线程
中循环来定时, 很吃CPU。 是不是有更好的办法?

我的问题主要出现在win98中, Win2k下工作好好的Timer,在98下问题多多。
 
用gettickcount比较合适,因为使用timer会出现延迟的现象,比如cpu非常繁忙时经常会
出现延迟触发或不触发的现象.
用gettickcount有两个好处
1.定时比较准,timer在interval在50一下就很不准了
2. 不会出现延迟现象.最后放在线程中处理,这样占资源会比较少.
 
多个timer一般不会互相干扰,多线程的timer会遇到那个问题,这可能都是没办法的
M$的windows2k还经常会出现这样问题呢
 
to www:
这是我改写的Timer中使用GetTickCount的部分。 可是很吃CPU啊!怎么改进?

{*********************************************
线程的Execute方法实做。 采用循环的方式来调用
Timer的OnTimer事件。
*********************************************}
procedure TTimerThread.Execute;
var
SleepTime, Last: DWord;
begin
while not tt.bStop do
begin
Last := GetTickCount();
SleepTime := tt.FInterval - ( GetTickCount() - Last );
if SleepTime < 5 then
SleepTime := 5;
//sleep( SleepTime );
MyDelay( SleepTime );
Synchronize( DoExecute ); //执行OnTimer中的代码
end;
end;

{*********************************************
此函数Copy自大富翁论坛。用于替换Sleep(X)函数。
因为Sleep函数不够精确。
*********************************************}
procedure TTimerThread.MyDelay(_D: DWord);
var
TmD: DWord;
begin
TmD := GetTickCount() + _D;
while (TmD > GetTickCount()) do
;
end;

To naughtboy:
你是说Timer不会干扰, 而两个独立线程的Timer会互相干扰?Why?

莫非,延迟触发或者不触发,真的是无法解决的问题?
 
http://www.neweasier.com/vcl.html?class=43
这里有很多,我感觉很好用
 
不会互相干扰吧,我听说实达铭泰的东方网神用了十几个Timer[:D]
 
to 老人家:
所有这些Timer,除了无源码的, 我全部都试验过。 在Win98下, 用两个Timer,
一个定时3分钟,一个定时15秒钟, 结果都不理想, 要么是不精确(5分钟误
差>1s), 要么是会不触发。
你感觉很好用的是哪个? 谢谢!
 
function timeBeginPeriod; external mmsyst name 'timeBeginPeriod';
function timeEndPeriod; external mmsyst name 'timeEndPeriod';
function timeGetDevCaps; external mmsyst name 'timeGetDevCaps';
function timeGetSystemTime; external mmsyst name 'timeGetSystemTime';
function timeGetTime; external mmsyst name 'timeGetTime';
function timeKillEvent; external mmsyst name 'timeKillEvent';
function timeSetEvent; external mmsyst name 'timeSetEvent';
 
在MMSystem单元里的函数,GetTickCount在98下误差大,在2000下也不太准确
 
看来是我的用法不对。 我把gettickcount都换成了timegettime,是一样的吃CPU。
等我试试TimeSetEvent.

另外, Sleep和SleepEx是怎么实现的延时? 精确性究竟如何?
 
to Town:
解决吃cpu没有太好的办法,有一个比较笨的办法就是在循环中加入
application.ProcessMessages;
我试验过,加的越多越好,当然不能太多,一般在循环的开始和结束加入就可以,cpu
占用率可以下降许多.

procedure TTimerThread.MyDelay(_D: DWord);
var
TmD: DWord;
begin
application.ProcessMessages;
TmD := GetTickCount() + _D;
while (TmD > GetTickCount()) do
   application.ProcessMessages; //这句一定要加

;
end;
 
不知道为什么, 用TimeSetEvent和TimeKillEvent做的Timer,在98下
设成3分钟的延时,结果就会在40多秒触发 :( 大家可以试试这个
控件: http://www.neweasier.com/downloadvcl.html?id=1984

其症状和我的问题1中的MMTools的Timer一模一样!!! 谁给解决了,
另出300分~~
 
这个可能是你的机器晶振不准了,你的机器时间是不是也跑的不准?
 
不会啊! 在2000下毫无问题, 而在98下就出这个问题。 40秒和3分钟的差距啊,
绝对不能用误差来解释 :(

而且, 这个问题在4台装了Win98的新计算机上测试, 全部都有这个问题。
 
GetTickCount 狂吃 CPU 是你的消息循环处理有问题,或根本没有进行消息循环处理。
 
顶部