BCB Timer定时时间小于执行时间

即:Timer的时间间隔为T1,其相应事件代码执行一遍的时间为T2,且T2>T1。
这样,一次未执行完毕,下一次定时到,这时候程序会如何执行?

可能的情况:
1、丢弃还未执行的代码,开始新的执行;
2、不丢弃,Timer消息进入消息队列排队,等到原来的代码执行完毕后,马上开始新的执行;

3、重入,就是原来的还继续执行,同时又开始一个新的执行;


正确的是第二种。

TTimer的内部实现,是通过API函数SetTimer实现的,设置定时器以后,会定时的通过消息通知。如果OnTimer事件的处理函数耗费时间过多,超出了Timer定时以后,这些消息是排了队的等候的,所以会越积越多。但是函数会执行完毕,不可能被丢掉重入。

至于为什么在定时器中i++好像没有效果,这是因为CPU一直在忙着,没有及时更新i的值。简单例程说明:
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    MessageDlg(IntToStr(i),mtInformation, TMsgDlgButtons() << mbOK, 0);
    i++;

    Application->ProcessMessages();
}

运行后可以看到,i的值是在变化的(当然,如果你很快的点击,还是能发现i的值变化并不规律,这还是因为线程在阻塞着)。

所以,如果在定时器的OnTimer中弹出消息框,最好是进入后先禁用定时器,出去时再启用定时器,如:
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    Timer1->Enabled = false;

    MessageDlg(IntToStr(i),mtInformation, TMsgDlgButtons() << mbOK, 0);
    i++;

     Application->ProcessMessages();

    Timer1->Enabled = true;
}


顺便补充一下,当禁用时Timer1->Enabled = false,其内部是通过API函数KillTimer实现的,启用时Timer1->Enabled = true, 其实只是再次用SetTimer设置定时器而已。

用科学的方法证明,比胡乱的猜测要好。

你可能感兴趣的:(c++builder)