线程中的timer无法工作(100分)

  • 主题发起人 主题发起人 Dale46
  • 开始时间 开始时间
D

Dale46

Unregistered / Unconfirmed
GUEST, unregistred user!
我给IdTCPClient添加了一个事件,如果连接后,1分钟没有会话就关闭连接。用Timer实现。Timer添加到了IdTCPClient类中。
当我在Form中创建一个IdTCPClient实例,Timer会正常工作(证明我的代码没有错)。
但我在Thread中创建一个IdTCPClient实例,
procedure TmyThread.Execute;
mytcp := TidTcpClient.Create(Application);

Timer将不会工作,Timer事件没有响应。
Why?如何才能让Timer工作。
我尝试过在相应的地方放入Application.processmessage,还是不行。
谢谢。
 
线程中缺省没有消息队列,无法响应Timer的消息,所以没反映,要么你在线程中加入消息队列,要么使用其他的定时器。具体参考Delphi深度历险。
 
请问如何在线程中加入消息队列?
我在Delphi深度历险中没有找到。
谢谢。
 
unit TestThread;

interface

uses Syncobjs, Windows, Messages, Classes, Sysutils, Controls, Forms;

type
{ TTestThread } //线程
TTestThread=class(TThread)
Private
Procedure OnTimer;
Procedure ShowMsg;
protected
procedure Execute;override;
public
Constructor Create(CreateSuspended: Boolean);
end;

implementation

{ TTestThread }

constructor TTestThread.Create(CreateSuspended: Boolean);
begin
//开始线程
Inherited Create(CreateSuspended);
end;

procedure TTestThread.Execute;
var FMessage:TMsg;
Timer:Integer;
begin
FreeOnTerminate:=True;
//建立线程内消息队列
PeekMessage(FMessage, 0, WM_USER, WM_USER, PM_NOREMOVE);
//建立检查定时器
Timer:=SetTimer(0,1,1000,nil);
//等待消息
While GetMessage(FMessage, 0, 0, 0) do
begin
Case FMessage.message of
WM_TIMER:OnTimer;
End;
//TranslateMessage(FMessage);
DispatchMessage(FMessage);
if Terminated then Break;
end;
KillTimer(0,Timer);
end;

procedure TTestThread.OnTimer;
begin
//你的OnTimer事件
Synchronize(ShowMsg);
end;

procedure TTestThread.ShowMsg;
begin
Application.Title:=FormatDateTime('HH:NN:SS.ZZZ',now);
end;

end.
 
用readtimeout属性来控制超时时间
 
type
tworkerThread=class(TThread)
private
Ftimer:timer;
procedure createTimerMethod //
procedure destroyTimerMethod //
procedure timerontimer(sender:Tobject)
protected
procedure execure;override;
public
constructor create;
destructor destroy;override;
end;
implementation

{tworkerThread}

constructor tworkerThread.create;
begin
inherited create(false);
synchronize(CreateTimerMethod);
end;

destructor tworkerThread.destroy;
begin
synchronize(destroyTimerMethod);
inherited destroy;
end;

procedure tworkerThread.createTimermethod;
begin
Ftimer:=TTimer.create(nil);
Ftimer.interval =30*1000;
FTimer.onTimer:=TimerOnTimer;
Ftimer.enabled:=true;
end;
procedure tworkerThread.destroyTimerMethod ;
begin
Ftimer.free;
end;

procedure tworkerThread.TimerOnTimer(sender:Tobject);
begin
.......................
end;

陈达宽的
 
谢谢cash95的提醒。

To TYZhang, WoDing. 我的理解是:如果要保证在线程中能正常响应timer事件,就必须把Timer写入Thread类中,而不能写在IdTCPClient类中。请问是吗?

另外,当Timer添加到了IdTCPClient类中。
我用:
procedure TmyThread.Execute;
begin
mytcp := TidTcpClient.Create(Application);
end;
Timer将不会工作,Timer事件没有响应。
但!我用:
constructor TTestThread.Create(CreateSuspended: Boolean);
begin
Inherited Create(CreateSuspended);
mytcp := TidTcpClient.Create(Application);
end;
Timer将会工作,Timer事件有响应。
请问这是为什么?

 
线程Create时候仍然在主线程中,所以能运行,线程真正开始运行是从Execute开始的,如果你把Timer申请在这当然不行。
WoDing,的例子也是可行的,因为它把Timer的创建也是放在主线程中的。
 
自己总结一下:
因为线程中缺省没有消息队列,所以无法响应Timer的消息。
解决方法,
要么在主线程中创建Timer,WoDing的例子。
要么在线程中加入消息队列,TYZhang的例子。
或者使用其他的定时器。
 
后退
顶部