13

我想在后台运行一个线程,它将检查与给定时间间隔的某些服务器的连接。例如每 5 秒。

我不知道这是否有一个好的“设计模式”?如果我没记错的话,我在某个地方读到过它的执行方法中的休眠线程并不好。但我可能错了。

另外,我可以使用普通的 TThread 类或 OTL 线程库。

有任何想法吗?

谢谢。

4

5 回答 5

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;

至于在 Execute 中睡觉 - 这取决于你是如何做到的。如果您使用睡眠,那么这可能不是很明智(例如,因为它会阻止线程在睡眠期间停止)。与 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 调度程序为最高优先级计时器指定适当的超时值。

于 2011-12-07T09:09:42.270 回答
14

您可以使用事件并通过等待事件的循环来实现后代的Execute方法,并指定超时。这样,您可以在需要时立即唤醒线程,例如在终止时。TThreadWaitForSingleObject

于 2011-12-07T08:38:40.730 回答
1

If the thread runs for the life of the app, can be simply terminated by the OS on app close and does not need accurate timing, why bother with solutions that require more typing than sleep(5000)?

于 2011-12-07T10:08:24.907 回答
1

To add another means of achieving a 5-sec event it is possible to use the Multimedia Timer which is similar to TTimer but has no dependence on your application. After configuring it (you can setup one-shot or repetitive) it calls you back in another thread. By its nature it is very accurate (to within better than 1ms). See some sample Delphi code here.

The code to call the timer is simple and it is supported on all Windows platforms.

于 2011-12-07T10:11:35.677 回答
0

使用CreateWaitableTimerSetWaitableTimer

于 2011-12-07T09:23:41.947 回答