我希望有一个后台线程,每隔一定时间(例如5秒)检查与某个服务器的连接状态。
我不知道是否有一个良好的“设计模式”来实现此功能?如果我没记错的话,我曾经在某个地方读到过在线程执行方法中休眠线程不是很好的做法。但是我可能错了。
此外,我可以使用普通的TThread类或OTL线程库。
有什么好的想法吗?
谢谢。
我希望有一个后台线程,每隔一定时间(例如5秒)检查与某个服务器的连接状态。
我不知道是否有一个良好的“设计模式”来实现此功能?如果我没记错的话,我曾经在某个地方读到过在线程执行方法中休眠线程不是很好的做法。但是我可能错了。
此外,我可以使用普通的TThread类或OTL线程库。
有什么好的想法吗?
谢谢。
在OmniThreadLibrary中,您需要这样做:
uses
OtlTask,
OtlTaskControl;
type
TTimedTask = class(TOmniWorker)
public
procedure Timer1;
end;
var
FTask: IOmniTaskControl;
procedure StartTaskClick;
begin
FTask := CreateTask(TTimedTask.Create())
.SetTimer(1, 5*1000, @TTimedTask.Timer1)
.Run;
end;
procedure StopTaskClick;
begin
FTask.Terminate;
FTask := nil;
end;
procedure TTimedTask.Timer1;
begin
// this is triggered every 5 seconds
end;
关于在Execute方法中休眠的问题,这取决于你的做法。如果你使用Sleep函数,那么这可能不是很明智的选择(例如因为它会阻止线程在休眠期间停止)。通过WaitForSingleObject函数进行休眠是可以的。
使用TThread和WaitForSingleObject函数的示例:
type
TTimedThread = class(TThread)
public
procedure Execute; override;
end;
var
FStopThread: THandle;
FThread: TTimedThread;
procedure StartTaskClick(Sender: TObject);
begin
FStopThread := CreateEvent(nil, false, false, nil);
FThread := TTimedThread.Create;
end;
procedure StopTaskClick(Sender: TObject);
begin
SetEvent(FStopThread);
FThread.Terminate;
FThread.Free;
CloseHandle(FStopThread);
end;
{ TTimedThread }
procedure TTimedThread.Execute;
begin
while WaitForSingleObject(Form71.FStopThread, 5*1000) = WAIT_TIMEOUT do begin
// this is triggered every 5 seconds
end;
end;
OTL计时器的实现方式类似于上面的TThread代码。OTL计时器被保存在优先级列表中(基本上是按“下一次发生”的时间对计时器进行排序),TOmniWorker中的内部MsgWaitForMultipleObjects分派程序指定了最高优先级计时器的适当超时值。
您可以使用一个事件,并通过带有WaitForSingleObject
等待事件的循环来实现TThread
子类的Execute
方法,指定超时时间。这样,当需要立即唤醒线程时,例如在终止时,就可以立即唤醒线程。
如果线程在应用程序的生命周期内运行,可以在应用程序关闭时被操作系统简单地终止,并且不需要精确的时间控制,那么为什么要使用比sleep(5000)更多的打字解决方案呢?
为了添加另一种实现5秒事件的方法,可以使用多媒体定时器。它类似于TTimer,但不依赖于您的应用程序。在配置它之后(您可以设置单次或重复),它会在另一个线程中回调您。由于其本质,它非常准确(精度高达1毫秒以下)。在此处查看一些Delphi示例代码。
调用定时器的代码很简单,并且支持所有Windows平台。