需要按时间监控某些数据,但要在没有打开监控窗口的情况下,实现监控。

解决方案 »

  1.   

    我觉得没有这个必要阿,其实timer控件的原理其实差不多就是用线程阿
      

  2.   

    不是吧?timer应该是每一段时间执行一次,而线程只要有余利,就执行,而没有的时候就不执行,这样该监控的时候不监控,不该监控的时候空耗资源。
      

  3.   

    线程中可以用TTimer,不过不是很好用,还不如直接用API, SetTimer,在线程中做一个消息循环。楼上说的好像不太对,任何一个进程运行着若干个线程(>=1),每个线程都认为自己是唯一的线程,也就是说各个线程的地位是平等的。
      

  4.   

    ttimer其实就是一个接受窗口wm_timer消息的不可见窗口。把它放在线程里面创建,再线程里面监测消息队列,响应wm_timer消息,用getmessage比peekmessape或者application.processmessages好,因为线程消息队列没有消息的时候,就不会空循环,不会累坏cpu:)如果你非要用线程来实现,也可以,给你个类,线程timer计时的。
    ////////////////////////////////////////
    unit Unit2;interfaceuses
      Classes,ExtCtrls,messages,windows;type
      TTimerThread = class(TThread)
      private
        Timer:TTimer;  protected
        procedure Execute; override;
      public
        procedure Resume;
        procedure Suspend;
        procedure SetInterval(Interval:integer);
        function GetInterval:integer;    constructor create(suspended:boolean;Interval:integer;OnTimerProc:TNotifyevent);
        destructor destroy;override;
      end;implementation
    { TTimerThread }constructor TTimerThread.create(suspended: boolean;Interval:integer;OnTimerProc:TNotifyevent);
    begin
      inherited create(true);
      timer:=ttimer.Create(nil);
      timer.OnTimer:=ontimerproc;
      timer.Interval:=interval;
      timer.Enabled:=false;
      if not suspended then
        resume;
    end;destructor TTimerThread.destroy;
    begin
      timer.Free;
      inherited;
    end;procedure TTimerThread.Execute;
    var
    msg:tmsg;
    begin
      while (not terminated)and getmessage(msg,0,0,0) do
      begin
          translatemessage(msg);
          dispatchmessage(msg);
      end;
    end;function TTimerThread.GetInterval: integer;
    begin
      result:=timer.Interval;
    end;procedure TTimerThread.Resume;
    begin
      timer.Enabled:=true;
      inherited;end;
    procedure TTimerThread.SetInterval(Interval: integer);
    begin
      timer.Interval:=interval;
    end;procedure TTimerThread.Suspend;
    begin
      timer.Enabled:=false;
      inherited;end;end.
      

  5.   

    线程中一般用Sleep()就可以了,还用tiomer反而效率不高。。
      

  6.   

    这个类几乎不用更改了,只要你在任何时候指定interval和在创建的时候指定了响应ontimer的过程就可以了。暂停监控的时候用suspend,继续监控用resume,停止监控free就可以了。
    下面是使用示范:
    /////////////////////////
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
        procedure OnTimer(sender:tobject);
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation
    uses
    unit2;
    var
    t:ttimerthread;
    {$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    begin
    t.Suspend;
    end;procedure TForm1.OnTimer(sender: tobject);
    begin
      beep;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      t:=ttimerthread.create(true,1000,ontimer);
      t.FreeOnTerminate:=true;
      t.Resume;
    end;procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
    t.Terminate;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
    t.Resume;
    end;end.
      

  7.   

    //上面的有问题,不能实现真正的线程控制的定时器。
    //换下面的吧:
    unit Unit3;interfaceuses
      Classes,sysutils,syncobjs;type
      TThreadTimer = class(TThread)
      private
        cs:tcriticalsection;
        Interval:integer;
        OnTimer:TNotifyEvent;  protected
        procedure Execute; override;
      public
        function GetInterval:integer;
        procedure SetInterval(Interval:integer);
        procedure SetOntimer(Ontimer:TNotifyEvent);
        function GetOnTimer:TNotifyEvent;
        /////////
        procedure SetEnabled(Enabled:boolean);
        function GetEnabled:boolean;
        /////////
        constructor Create(Interval:integer;Ontimer:TNotifyEvent);
        destructor Destroy;override;
      end;implementation
    { TThreadTimer }constructor TThreadTimer.Create(Interval: integer; Ontimer: TNotifyEvent);
    begin
      inherited create(true);
      self.Interval:=interval;
      self.OnTimer:=ontimer;
      freeonterminate:=true;
      cs:=tcriticalsection.Create;end;destructor TThreadTimer.Destroy;
    begin
      cs.Free;
      inherited;
    end;procedure TThreadTimer.Execute;
    var
    i:integer;
    begin
      while not terminated do
      begin
        cs.Enter;
        i:=interval;
        cs.Leave;
        sleep(i);
        cs.Enter;
        try
        if assigned(ontimer)then
          ontimer(self);
        finally
        cs.Leave;
        end;
      end;
    end;function TThreadTimer.GetEnabled: boolean;
    begin
      result:=self.Suspended;
    end;function TThreadTimer.GetInterval: integer;
    begin
      cs.Enter;
      result:=interval;
      cs.Leave;
    end;function TThreadTimer.GetOnTimer: TNotifyEvent;
    begin
      cs.Enter;
      result:=ontimer;
      cs.Leave;
    end;procedure TThreadTimer.SetEnabled(Enabled: boolean);
    begin
      if enabled then
        resume
      else
        suspend;
    end;procedure TThreadTimer.SetInterval(Interval: integer);
    begin
      cs.Enter;
      self.Interval:=interval;
      cs.Leave;
    end;procedure TThreadTimer.SetOntimer(Ontimer: TNotifyEvent);
    begin
      cs.Enter;
      self.OnTimer:=ontimer;
      cs.Leave;
    end;
    end.
    ////////////////////////////////////////////////
    //测试代码如下:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,unit3;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        procedure OnTimer(sender:tobject);
      public
        { Public declarations }
        t1:tthreadtimer;
      end;var
      Form1: TForm1;implementation
    {$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    begin
    t1.SetEnabled(false);
    end;procedure TForm1.OnTimer(sender: tobject);
    begin
      beep;
    end;procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
    t1.Terminate;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
    t1.SetEnabled(true);
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
    sleep(10000);//主线程死锁也不会影响定时线程。self.ontimer依然会被调用。
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
    t1:=tthreadtimer.Create(1000,ontimer);
    t1.SetEnabled(true);
    end;end.