我想在后台运行一个线程,它会在给定的时间间隔内检查与某个服务器的连接。例如,每5秒钟。
我不知道这是否有一个好的“设计模式”?如果我记得正确的话,我已经读过一些在其执行方法中睡眠线程不好的地方。但我可能错了。
另外,我可以使用普通的TThread类或OTL线程库。
有什么想法吗?
感谢。
答案 0 :(得分:16)
在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;
至于在执行中睡觉 - 这取决于你如何做。如果你使用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调度程序为最高优先级定时器指定适当的超时值。
答案 1 :(得分:14)
您可以使用事件并通过Execute
等待事件的循环实现TThread
后代的WaitForSingleObject
方法,指定超时。这样,您可以在需要时立即唤醒线程,例如终止时。
答案 2 :(得分:1)
如果线程在应用程序的生命周期中运行,可以通过应用程序关闭的操作系统终止,并且不需要准确的计时,为什么还需要更多打字而不是睡眠(5000)?
答案 3 :(得分:1)
要添加另一种实现5秒事件的方法,可以使用类似于TTimer的多媒体计时器,但不依赖于您的应用程序。配置后(您可以设置一次性或重复性),它会在另一个线程中回拨您。就其性质而言,它非常准确(在1ms以内)。查看一些sample Delphi code here。
调用计时器的代码很简单,所有Windows平台都支持它。
答案 4 :(得分:0)