为什么在使用这个多线程timer后窗体无法关闭,在delphi7下调试,delphi也无响应了,是怎么回事?
//多线程Timerunit ThrdTimer;interfaceuses
  Windows, Messages, SysUtils, Classes,
  Graphics, Controls, Forms, Dialogs;type
  TThreadedTimer = class;  TTimerThread = class(TThread)
    OwnerTimer: TThreadedTimer;
    Interval: DWord;
    procedure Execute; override;
    procedure DoTimer;
  end;  TThreadedTimer = class(TComponent)
  private
    FEnabled: Boolean;
    FInterval: Word;
    FOnTimer: TNotifyEvent;
    FTimerThread: TTimerThread;
    FThreadPriority: TThreadPriority;
  protected
    procedure UpdateTimer;
    procedure SetEnabled(Value: Boolean);
    procedure SetInterval(Value: Word);
    procedure SetOnTimer(Value: TNotifyEvent);
    procedure SetThreadPriority(Value: TThreadPriority);
    procedure Timer; dynamic;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;    procedure Reset;
  published
    property Enabled: Boolean read FEnabled write SetEnabled default True;
    property Interval: Word read FInterval write SetInterval default 1000;
    property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
    property ThreadPriority: TThreadPriority read FThreadPriority
      write SetThreadPriority;
  end;procedure Register;implementationprocedure TTimerThread.Execute;
begin
   repeat
      SleepEx(Interval, False);
      Synchronize(DoTimer);
   until Terminated;
end;procedure TTimerThread.DoTimer;
begin
   OwnerTimer.Timer;
end;constructor TThreadedTimer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FEnabled := True;
  FInterval := 1000;
  FThreadPriority := tpNormal;
  FTimerThread := TTimerThread.Create(False);
  FTimerThread.OwnerTimer := Self;
  FTimerThread.Interval := FInterval;
  FTimerThread.Priority := FThreadPriority;
end;destructor TThreadedTimer.Destroy;
begin
  FEnabled := False;
  UpdateTimer;
  FTimerThread.Free;
  inherited Destroy;
end;procedure TThreadedTimer.UpdateTimer;
begin
   if FTimerThread.Suspended = False then
      FTimerThread.Suspend;   if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
      FTimerThread.Resume;
end;procedure TThreadedTimer.SetEnabled(Value: Boolean);
begin
   if Value <> FEnabled then
   begin
      FEnabled := Value;      UpdateTimer;
   end;
end;procedure TThreadedTimer.SetInterval(Value: Word);
begin
   if Value <> FInterval then
   begin
      FInterval := Value;
      FTimerThread.Interval := FInterval;
      UpdateTimer;
   end;
end;procedure TThreadedTimer.SetOnTimer(Value: TNotifyEvent);
begin
   FOnTimer := Value;
   UpdateTimer;
end;procedure TThreadedTimer.SetThreadPriority(Value: TThreadPriority);
begin
   if Value <> FThreadPriority then
   begin
      FThreadPriority := Value;
      FTimerThread.Priority := Value;
      UpdateTimer;
   end;
end;procedure TThreadedTimer.Timer;
begin
   if Assigned(FOnTimer) then
      FOnTimer(Self);
end;
procedure TThreadedTimer.Reset;
begin
   FTimerThread.Free;
   FTimerThread := TTimerThread.Create(False);
   FTimerThread.OwnerTimer := Self;
   FTimerThread.Priority := FThreadPriority;
   UpdateTimer;
end;
procedure Register;
begin
   RegisterComponents('System', [TThreadedTimer]);
end;end.

解决方案 »

  1.   

    怎么没人会,delphi版这差了??
      

  2.   

    ??Timer 做成独立的一个线程,你就自己建立一个消息循环处理自己的消息,建立线程LIST,系统关闭时,
    向Timer线程SendMessage Wm_close
      

  3.   

    procedure TTimerThread.Execute; 
    begin 
      repeat 
          SleepEx(Interval, False); 
          Synchronize(DoTimer); 
      until Terminated; 
    end; 
    modify to ==>
    自己完成消息队列的处理。
    while (not Terminated) and getmessage(Msg,0,0,0) do   
    begin   
      Translatemessage(Msg);   
      Dispatchmessage(Msg);   
    end;   
      

  4.   


    //请教一下LZ,为什么你不用Timer控件,而自己重新做了一个?不过自己做的那个也不对啊,没有为Timer分配Handle,刚定时器把WM_TIMER投递到消息队列后,Dispatchmessage如何把消息分配到窗口函数上?
    //WM_TIMER有堵塞现象,在下一个消息到达时应该用UpdateTimer来重置一下!
    以下代码纯手写,没用Delphi的线程类,权当参考吧!
    function MyThreadFun(p: Pointer): DWORD; stdcall;
    var
      TM:TTimer;
    begin
      TM:=TTimer.Create;
      Try
        With TM do
        begin 
          Enabled:=False;
          Enabled:=True;
          Interval:=XXX;
          OnTimer:=TimerProc;
        end;
        While GetMessage(Msg, 0, 0, 0) and (not Terminated) do
        begin
          Translatemessage(Msg);   
          Dispatchmessage(Msg);  
        end; 
      finally
        TM.Free;
      end;
    end;
    procedure TimerProc
    begin
      //xxxxx
    end;
    //Run the thread
    hThread := CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
      

  5.   


    //被华仔的回复误导了:)修改一下消息循环部分
    //当发送完WM_CLOSE后自动用等待关闭线程策略来实现线程关闭!
    //按照华仔的做法,需要在类外先对线程进行关闭而后再发送关闭消息,而这样写仅需要直接发送一个WM_CLOSE即可!
     While GetMessage(Msg, 0, 0, 0) and  do
        begin
          Translatemessage(Msg);   
          Dispatchmessage(Msg);  
        end; 
      Terminate;
      

  6.   

    //笔误:应该是发送WM_QUIT,退出消息循环:)