警惕程序中数据类型不一致导致错误

1,问题的缘由

本人在编程中需要在线程中定期执行某个任务,于是将上次执行任务的时间进行标记,在线程的execute循环中,每次循环都判断当前时间与上次执行时间是否已经达到指定的时间间隔,若是才执行。

 

具体代码如下:

procedure Thread_chargeControllerIntf.Execute;

begin

  if not PreprareWork then exit;

 

  while not FStop do

  try

    DoWork;

    sleep(1000);

    KeepDBConnection;

 

  except

    on e:Exception do

      try

        addLog_fromThread('Thread_chargeControllerIntf执行出错:'+ e.Message);

      except

 

      end;

  end;

 

end;

 

 

procedure Thread_chargeControllerIntf.KeepDBConnection;

begin

  //防止 GetTickCount函数重新计数

  if self.FLastKeepTick > GetTickCount() then

FLastKeepTick := 0;

 

  //每小时执行一次  

  if  GetTickCount() - FLastKeepTick < 3600*1000 then

    Exit;

 

  FLastKeepTick := GetTickCount();

  uFunc.ThreadQuery('select 1');

  addLog_fromThread('KeepDBConnection.');

end;

 

 

该线程通过调用KeepDBConnection函数,达到每小时访问一次mysql数据库,以保持数据库连接不被DBMS中断的目的。

其中,FLastKeepTick integer类变量,保存上次执行数据库查询的时间。

 

该段代码以前正常运行,每小时执行一次。但最近却突然发现,变为每秒执行一次。

日志如下:

2021-01-20 08:40:38 KeepDBConnection.

2021-01-20 08:40:39 KeepDBConnection.

2021-01-20 08:40:40 KeepDBConnection.

2021-01-20 08:40:41 KeepDBConnection.

2021-01-20 08:40:42 KeepDBConnection.

 

2,问题分析

代码跟踪发现,FLastKeepTick在存储GetTickCount()返回的数值时,没有如想象中为正整数,而是变为了负值。如:

2021-01-20 08:42:04 FLastKeepTick=-1832924107

2021-01-20 08:42:04 GetTickCount=2462044189

 

 

可见,FLastKeepTick在存储时,并不是存为2462044189,因为该值已经超出integer的范围,导致其存为相应的负值,即 2462044189- 4294967296(256*256*256*256) =-1832924107

 

3,问题解决

找到原因,解决问题很简单,就是要将FLastKeepTick声明为DWord类型,而不是integer类型,而且GetTickCount函数的返回类型本来就是DWord类型。

 

实测将FLastKeepTick声明为DWord类型后,程序恢复正常,问题解决。

posted @ 2021-01-20 09:25  jack0424  阅读(333)  评论(0编辑  收藏  举报