为什么在使用这个多线程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.
//多线程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.
解决方案 »
- 请教cxgrid汇兑的问题(多列相加)
- 如何自动输入数据到某个软件界面上
- 喜歡了公司的一個女孩,想追,希望兄弟們能提供泡妞完美攻略。
- 散点分,请朋友们指点迷津。
- 如何剪切、复制、粘贴控件(关于剪贴板的问题),答对分数还可以再加!!!!
- 有人用过TValueListEditor控件么?
- 救命啊!!webbrowser1.ExecWB(OLECMDID_SAVEAS,OLECMDEXECOPT_DODEFAULT);
- delphi有给数组整体赋值的方法吗?
- 如何使listview单元格中的数据可以进行修改?
- 想用一个循环来实现,请问如何做?
- 关于DELPHI 线程堆栈问题,应该如何修改呢
- delphi button上添加bmp图片 怎样将其中的底色透明
向Timer线程SendMessage Wm_close
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;
//请教一下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);
//被华仔的回复误导了:)修改一下消息循环部分
//当发送完WM_CLOSE后自动用等待关闭线程策略来实现线程关闭!
//按照华仔的做法,需要在类外先对线程进行关闭而后再发送关闭消息,而这样写仅需要直接发送一个WM_CLOSE即可!
While GetMessage(Msg, 0, 0, 0) and do
begin
Translatemessage(Msg);
Dispatchmessage(Msg);
end;
Terminate;