delphi中的timer组件interval是设置延时的
要是ontimer里的事件处理时间大于interval所设置延时,是否在执行ontimer里的事件时候,timer又会再次被激活?也就是没有执行完ontimer事件后又再次被激活而反复执行,要是这样,有什么方法能避免这种事件发生,不管ontimer里的事件执行需要多长时间,都把它执行完后才再次定时,请给出源码.

解决方案 »

  1.   

    使用象信号量等线程同步的方法来同步你的事件处理。(时间上连续)
    或者干脆在调用函数的时候将enable false了,调用完了之后在true过来(时间上不连续)
      

  2.   

    interval是延时的吗,晕!!!
    ONTIMER 事件每隔INTERVAL的时间 就执行一次!!!
    像你的想法不会出现!!
      

  3.   

    interval是延时的吗,晕!!!
    ONTIMER 事件每隔INTERVAL的时间 就执行一次!!!
    像你的想法不会出现!!
    这才是真正的高手!!!!!!!!!!!11
      

  4.   

    ziqing(紫情)
    是啊,我知道到是每隔interval所设定的时间就执行ONTIMER 事件,但是要是ONTIMER 事件执行的速度也就是耗费的时间大于interval所设定的时间,那程序是继续执行完还是直接又重新触发重头执行???
      

  5.   

    自己设置一个标志Boolean。
    开始设置为true,执行开始后设置为false,执行完了再设置为true。
    开始执行的时候都要先检查标志是否为true;
      

  6.   

    我想应该是执行完后,再过interval再执行
      

  7.   

    timer1.enabled:=false;
    timer1.interval:=5000;
    timer1.enabled:=true;
    这样不行吗?
      

  8.   

    呵呵interval
    n.间隔;休息;间距
      

  9.   

    procedure ontimer
    begin
       timer.enable:= false;
       //do something;
       timer.enable:= true;
    end;
      

  10.   

    你可以用两个TIMER 一个设置时间 长的和一个时间 短的,用短的来控制长的TIMER的EABLE
    在长的TIMER 里发生事件 !!
      

  11.   

    cnhgj(黄桂佳 → 吃软不吃硬) 

    我那个程序是毫秒级的越快越好,向你这么设置怎么用??
      

  12.   

    procedure ontimer
    begin
       if excute then exit;
       excute:= true;
       //do something;
       excute:= false;
    end;
      

  13.   

    :)Timer 事件是在主线程里执行的,当你的一个 Timer 事件没有完成时,主线程不会再响应你的第二个 Timer 事件
    我是菠菜,非高手!
      

  14.   

    :)Timer 事件是在主线程里执行的,当你的一个 Timer 事件没有完成时,主线程不会再响应你的第二个 Timer 事件
    我是菠菜,非高手!
      

  15.   

    to  shuixin13(犬犬(心帆)) 
        在拿我开玩笑吗?*^_^*
      

  16.   

    shuixin13(犬犬(心帆)) 是对得!你这么看看就行了,全局变量i是依次被加到listbox中的,interval=1000procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      inc(i);
      sleep(3000);
      ListBox1.Items.Add(inttostr(i));
    end;
      

  17.   

    shuixin13(犬犬(心帆)) 是对得!你这么看看就行了,全局变量i是依次被加到listbox中的,interval=1000procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      inc(i);
      sleep(3000);
      ListBox1.Items.Add(inttostr(i));
    end;
      

  18.   

    Timer利用消息机制,只要你的OnTimer事件中不处理后续的消息,不会产生第二次OnTimer
    但是如果调用了Application.ProcessMessages或MessageBox等,则可能会产生第二次OnTimer
      

  19.   

    shuixin13(犬犬(心帆)) 是对得!你这么看看就行了,全局变量i是依次被加到listbox中的,interval=1000procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      inc(i);
      sleep(3000);
      ListBox1.Items.Add(inttostr(i));
    end;
      

  20.   

    这个问题值得探讨,我以前以为是:只要时间到,就执行TIMER事件,但楼上又有高手说如果没执行完,是不会响应第二次事件?看来我要再去查资料或做实验了。
      

  21.   

    如果在ontimer事件中的代码是开线程呢,会很麻烦
    我记得我以前作过一个定时扫描端口的程序,单独使用了一个线程来执行端口扫描,如果不做同步的话会跑出一堆错误来。
      

  22.   

    而且这样procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      inc(i);
      sleep(3000);
      ListBox1.Items.Add(inttostr(i)+':'+FormatDateTime('ss',now));
    end;
    你会发现,他们的时间间隔是3秒!不是4秒!
    看来当前一个timer事件没完成时,后一个timer事件是处于等待状态的,用 小查 的 回复,Timer利用消息机制,那正好解释了这个现象  
     
      

  23.   

    高手真多
    小弟还有个问题就是:
    Timer里的interval设置是不是在不同配置的电脑里所延长的时间是一样的?
    比如386和P4机器运行同一个程序,延长时间是一样吗?还有误差吗?
    要是不一样有什么解决方法能解决,最好也给出代码,分不够我也会加.
      

  24.   

    :) 
    Timer 的定时的确是不稳定的,
    不同的机器会有点差别
      

  25.   

    没太明白你说的意思。
    先按我的理解给出答案。
    这个问题你大可以设置两个TIMER。
    代码如下
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      timer1.Enabled:=fasle;
    //your code
      timer2.Enabled:=true;
    end;procedure TForm1.Timer2Timer(Sender: TObject);
    begin
      timer1.Enabled:=true;
      timer2.Enabled:=fasle;
    end;
    //说明一下,这个程序是我进行轮询的时候用的,timer1的interval设置为300
    timer2的interval设置为3000,在初始之前,设置timer1。Enabled:=ture;
    timer2.Enabled:=false;
    也就是说,TIMER1的ontime触发时,不会再进行轮询,直到处理完,间隔3秒后再进行轮询
    最后要说明一下,itmer控件是响应windows的WM_Timer消息的,属于回叫函数。
    不同于sleep()函数。
    具体的消息循环之类的概念,你可以参考关于windows下的消息之类的参考资料。
      

  26.   

    那要怎么办才能稳定,要求在1ms-5ms
      

  27.   

    timer的时间稳定是不可能的,因为和消息处理速度有关。
    如果要求1ms-5ms这么高的时间稳定性,那只能说,你用错了操作系统。
    windows本身的消息机制限制了它是不可能达到的。
      

  28.   

    有一些方法,还是基本能达到 1ms-5ms 的要求,但不是 100% 可靠
    1  多媒体库(mmSystem?)中有一个函数(mmTimer?),可以试一试
    2  用一个线程(必要时优先级设高点),结合 QueryPerformanceFrequency 和
       QueryPerformanceCounter 确定时间间隔(不要用Sleep,它很不准),再执行相应操作
      

  29.   

    要想在 WIN32 下得到精确的计时有两个方法:
    建立线程使用下面的两个方法之一定时1: 
    var  FStop: THandle;FInterval := 100;
    FStop := CreateEvent(nil, False, False, nil);
    if WaitForSingleObject(FStop, FInterval) = WAIT_TIMEOUT then ......2:
    GetTickCount