API里面Timer相关的函数。直接可以在delphi的帮助里面查到的。

解决方案 »

  1.   

    type
      TMyThread = class(TThread)
        private
          FTimer:TTimer;
          procedure TimerProc(Sender: TObject);
        protected
          procedure Execute;override;
        public
          constructor Create;override;
          procedure KillIt;//结束
      end;
    implementation
      procedure TMyThread.TimerProc(Sender: TObject);
      begin
        ...
      end;
      procedure TMyThread.KillIt;
      begin
        PostThreadMessage(ThreadNo,WM_QUIT,0,0);
      end;
    procedure TMyThread.Execute;
    begin
      FTimer:=TTimer.Create(nil);
      try
          FTimer.Enabled:=false;//需要用的时候Enabled设置为True即可。
          FTimer.OnTimer:=TimerProc;
          while GetMessage(MsgRec, 0, 0, 0) do begin
            TranslateMessage(MsgRec);
            DispatchMessage(MsgRec)
          end;
          Terminate;
      finally
        FTimer.Free;
      end;
    end;
    要结束的话,往线程的Handle发送一个WM_QUIT消息,本例当中调用KillIt var 
      T: TMyThread; 
    begin 
      ... 
      T.KillIt; 
    end;
      

  2.   

    楼上的就行了, 在thread.create 的时候应创建timer对象及设置timer 的属性
      

  3.   

    Thread.Create当中创建的会是在当前线程(主线程)当中执行的,在Thread.Execute当中创建的才是在该线程当中的。也就是WM_TIMER被投递的线程会是不一样的。否则的话,就不是线程当中的Timer.
      

  4.   

    //请教一下僵哥,为什么在线程的构造函数中创建Timer后,当线程中有时间消息时就会把WM_TIMER投递给主线程队列呢?
    //另外,僵哥,用线程周期性阻塞是不是也可以//线程类
    unit Unit2;interfaceuses
      Classes,sysutils,SyncObjs,Dialogs;
    type
      TTest = class(TThread)
      private
        { Private declarations }
        FSum:Integer;
        procedure UpdateCaption;
      protected
        procedure Execute; override;
      public
        constructor Create(CreateSuspended: Boolean);
      end;
    implementation
    uses Unit1;procedure TTest.UpdateCaption;
    begin
      Form1.Edit1.Text := Inttostr(FSum);
      showmessage('Sum Process End');
    end;procedure TTest.Execute;
    begin
    //必须循环来判断Terminated标志
      while not Terminated do
      begin
        FSum:=FSum+1;//这里可以执行其它独立的任务,例如生成带有独立任务的线程
        case QuitEvent.WaitFor(60*100) of  //阻塞时间,即Timer.Interval
          wrSignaled, wrAbandoned: Terminate;
        end;
          Synchronize(UpdateCaption);//实现问题2,把函数放在这里,是为了更直观地看到当前执行的结果
      end;
      { Place thread code here }
    end;constructor TTest.Create(CreateSuspended: Boolean);
    begin
      inherited;
      FSum:=0;
    end;end.
    //主线程代码
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,SyncObjs;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
      procedure NotifySumThreadsToQuit;var
      Form1: TForm1;
      QuitEvent: TEvent;//事件说白了就是一个全局的布尔变量,用SetEvent置为一种状态,便于在线程循环时根据该标识来将线程中止
    implementationuses Unit2;{$R *.dfm}procedure NotifySumThreadsToQuit;
    begin
      QuitEvent.SetEvent;//置信号
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      Thd:TTest;
    begin
      Thd:=TTest.Create(True);
      Thd.FreeOnTerminate:=False;
      Thd.Resume;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
       NotifySumThreadsToQuit//通知线程结束
    end;initialization
      QuitEvent := TEvent.Create(nil,true,false,'SumProcessEnd');//创建事件finalization
      QuitEvent.Free;//释放事件
    end.
      

  5.   

    to 楼上。消息队列是以线程为基础的。线程构造函数实际只是由主线程调用的一个过程。其代码是在主线程中运行的。
    因此,在线程构造函数中创建一个Timer对象实际就是主线程创建了一个Timer对象,因此WM_TIMER消息只会进入主线程的消息队。真正的线程执行代码只会在线程对象的Execute部分存在。
      

  6.   

    明白了,明白了,谢谢蒲石大哥!
    刚才被Delphi封装的线程类迷惑了!
    看了一下其类实现,明白了!就是要把创建Timer的过程写在CreateThread的回调函数中才能达到目的!
      

  7.   

    这问题,可能更好的方法是使用 CreateWaitableTimer
      

  8.   

    WaitableTimer实际也需要一个wait阻塞或者不断循环。相比之下多媒体定时器应该是比较好的选择,多媒体定时器本身就是一个线程。
      

  9.   

    while GetMessage(MsgRec, 0, 0, 0) do begin
            TranslateMessage(MsgRec);
            DispatchMessage(MsgRec)
          end;VCL消息处理^_^
      

  10.   

    LZ是想要线程安全的,2楼给的确是非线程安全的,其中陷阱不少哦
    最好的方法是在线程执行过程中自己手动创建一个窗口。那么这个窗口的消息投递就会在这个线程中了。你想要TIMER,那就可以SETWINDOWTIMRE,在消息循环中相应WM_Timer我以前倒是写过一个这样的代码,不记得在不在我的BLOG里了。有星期可以去看看。
      

  11.   

    最好的方法是在线程执行过程中自己手动创建一个窗口。那么这个窗口的消息投递就会在这个线程中了。
    --------------------------------------------------------------------------------
        楼上的,自己去看看Delphi的TTimer是怎么实现的(没记错的话,是通过AllocateHandle创建了一个窗体,也就是说是TTimer就是通过窗体响应WM_TIMER消息实现的)。