解决GetTickCount的问题

本文探讨了GetTickCount API在长时间计时应用中的局限性,特别是在计算机运行49.7天后计数值重置的问题。提供了一种巧妙的解决方案,通过特定的判断逻辑确保即使在计数溢出后,仍能准确判断对象是否超过了预设的超时时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GetTickCount是一个api,它是反应到从开机到当前的毫秒数,这个很好.可以做一些短途的计时器.

比如说做服务器中对象池计时器,对象超过多少时间就自动释放对象.

 

但是GetTickCount也有一个麻烦的地方,就是在电脑运行了49.7天之后,数字会置0 ,然后从0开始.这样的话,简单的时间判断可能会造成49.7天后的bug,那么怎办呢?其实可以用一点小技巧就可以解决.

看下面的代码,Judge1是判断函数,

i     是当前的计时点
OutSec  是超时秒数.
NowTick  是当前的Tick,即当前时间点.

可以看到以下的测试代码模拟了几种计时起点和当前的Tick,但是神奇的判断Judge1都可以把时间正确判断.

 

rocedure TForm4.FormCreate(Sender :TObject);
var
  I       :UInt64;
  NowTick :LongWord;

  OutSec :Word;

  procedure Judge1();
  var
    Tmp :UInt64;
  begin
    Tmp := I + OutSec * 1000;     //时长右边界

    if Tmp > LongWord.MaxValue then begin
      if (I > NowTick) and (NowTick > Tmp - Longword.MaxValue) then
        ShowMessage('ok2');
    end
    else begin
      if NowTick >= I then begin
        if NowTick > Tmp then
          ShowMessage('ok1');
      end
      else
        ShowMessage('ok3');
    end;
  end;

begin
  I := 10;          //i是时长左边界
  OutSec := 2;      //超时秒数
  NowTick := 2020;    //当前时间
  Judge1();

  I := 10;
  OutSec := 2;
  NowTick := 2010;
  Judge1();

  I := 10;
  OutSec := 2;
  NowTick := 2009;
  Judge1();

  I := Longword.MaxValue - 3000;
  OutSec := 2;
  NowTick := Longword.MaxValue - 2000;
  Judge1();

  I := Longword.MaxValue - 3000;
  OutSec := 2;
  NowTick := Longword.MaxValue - 1000;
  Judge1();

  I := Longword.MaxValue - 3000;
  OutSec := 2;
  NowTick := Longword.MaxValue - 999;
  Judge1();

  I := Longword.MaxValue - 3000;
  OutSec := 2;
  NowTick := 5;
  Judge1();

  I := Longword.MaxValue - 3000;
  OutSec := 2;
  NowTick := Longword.MaxValue - 50;
  Judge1();

  I := Longword.MaxValue - 300;
  OutSec := 2;
  NowTick := Longword.MaxValue - 50;
  Judge1();

  I := Longword.MaxValue - 300;
  OutSec := 2;
  NowTick := 20;
  Judge1();

  I := Longword.MaxValue - 300;
  OutSec := 2;
  NowTick := 1700;
  Judge1();

  I := Longword.MaxValue - 300;
  OutSec := 2;
  NowTick := 1701;
  Judge1();

end;

 

转载于:https://www.cnblogs.com/IDELPHI/p/GetTickCount.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值