如何在新开的线程中实现定时器的功能?

xiaolei_418 2004-03-16 04:05:08
我想在新开的线程中实现如Timer控件的功能
每隔X秒向服务器发一次消息
...全文
248 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
aiirii 2004-03-17
  • 打赏
  • 举报
回复
stanely 的例子,
ontimer 是個函數!
xiaolei_418 2004-03-17
  • 打赏
  • 举报
回复
stanely(俺是邢她汉子)
你能否再说详细一点!!谢谢!1
postren 2004-03-16
  • 打赏
  • 举报
回复
可以用GetTickCount;来获取时间,再加上Sleep配合
stanely 2004-03-16
  • 打赏
  • 举报
回复
如果你这个线程就起一个定时器的作用,有个轻便的解决方法:
线程定义一个变量
比如ontimer:tnotifyevent;
然后你可以在execute里面写
while not terminated do
begin
sleep(1000);//你需要的interval
if assigned(self.ontimer) then ontimer(self);
end;
这时候,ontimer就在你的新线程里面执行。
当然,最好和服务器通信是"阻塞"的,功能设计得分散些,自定义函数多用些参数,少用共享资源比如全局变量,可以避免很多多线程带来的复杂性。

BeyondStudio 2004-03-16
  • 打赏
  • 举报
回复
线程是没有窗体的,所以也不会收到 WM_TIMER 事件,具体如何解决,请参看 Delphi 深度历险。

下面是一个线程定时器控件:
////////////////////////////////////////////////////
// //
// ThreadedTimer 1.2a //
// //
// Copyright (C) 1996, 2000 Carlos Barbosa //
// email: delphi@carlosb.com //
// Home Page: http://www.carlosb.com //
// //
// Portions (C) 2000, Andrew N. Driazgov //
// email: andrey@asp.tstu.ru //
// //
// Last updated: November 24, 2000 //
// //
////////////////////////////////////////////////////

unit ThdTimer;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

const
DEFAULT_INTERVAL = 1000;

type
TThreadedTimer = class;

TTimerThread = class(TThread)
private
FOwner: TThreadedTimer;
FInterval: Cardinal;
FStop: THandle;
protected
procedure Execute; override;
end;

TThreadedTimer = class(TComponent)
private
FOnTimer: TNotifyEvent;
FTimerThread: TTimerThread;
FEnabled: Boolean;

procedure DoTimer;

procedure SetEnabled(Value: Boolean);
function GetInterval: Cardinal;
procedure SetInterval(Value: Cardinal);
function GetThreadPriority: TThreadPriority;
procedure SetThreadPriority(Value: TThreadPriority);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

published
property Enabled: Boolean read FEnabled write SetEnabled default False;
property Interval: Cardinal read GetInterval write SetInterval default DEFAULT_INTERVAL;
property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
property ThreadPriority: TThreadPriority read GetThreadPriority write SetThreadPriority default tpNormal;
end;

procedure Register;

implementation

{ TTimerThread }

procedure TTimerThread.Execute;
begin
repeat
if WaitForSingleObject(FStop, FInterval) = WAIT_TIMEOUT then
Synchronize(FOwner.DoTimer);
until Terminated;
end;

{ TThreadedTimer }

constructor TThreadedTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FTimerThread := TTimerThread.Create(True);
with FTimerThread do
begin
FOwner := Self;
FInterval := DEFAULT_INTERVAL;
Priority := tpNormal;

// Event is completely manipulated by TThreadedTimer object
FStop := CreateEvent(nil, False, False, nil);
end;
end;

destructor TThreadedTimer.Destroy;
begin
with FTimerThread do
begin
Terminate;

// When this method is called we must be confident that the event handle was not closed
SetEvent(FStop);
if Suspended then
Resume;
WaitFor;
CloseHandle(FStop); // Close event handle in the primary thread
Free;
end;
inherited Destroy;
end;

procedure TThreadedTimer.DoTimer;
begin

// We have to check FEnabled in the primary thread
// Otherwise we get AV when the program is closed
if FEnabled and Assigned(FOnTimer) then
FOnTimer(Self);
end;

procedure TThreadedTimer.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
if FEnabled then
begin
if FTimerThread.FInterval > 0 then
begin
SetEvent(FTimerThread.FStop);
FTimerThread.Resume;
end;
end
else
FTimerThread.Suspend;
end;
end;

function TThreadedTimer.GetInterval: Cardinal;
begin
Result := FTimerThread.FInterval;
end;

procedure TThreadedTimer.SetInterval(Value: Cardinal);
var
PrevEnabled: Boolean;
begin
if Value <> FTimerThread.FInterval then
begin

// We must restore the previous state of the Enabled property
PrevEnabled := FEnabled;
Enabled := False;
FTimerThread.FInterval := Value;
Enabled := PrevEnabled;
end;
end;

function TThreadedTimer.GetThreadPriority: TThreadPriority;
begin
Result := FTimerThread.Priority;
end;

procedure TThreadedTimer.SetThreadPriority(Value: TThreadPriority);
begin
FTimerThread.Priority := Value;
end;

procedure Register;
begin
RegisterComponents('System', [TThreadedTimer]);
end;

end.
xiaolei_418 2004-03-16
  • 打赏
  • 举报
回复
有人会吗?

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧