Multithreading 如何实现使用最少资源定期检查某些内容的线程?

Multithreading 如何实现使用最少资源定期检查某些内容的线程?,multithreading,delphi,delphi-2009,tthread,omnithreadlibrary,Multithreading,Delphi,Delphi 2009,Tthread,Omnithreadlibrary,我想有一个线程在后台运行,它将检查连接到某个给定的时间间隔服务器。例如,每5秒 我不知道这是否有一个好的“设计模式”?如果我没有记错的话,我在这里读到过一些文章,说执行方法中的休眠线程不好。但我可能错了 另外,我可以使用普通的TThread类或OTL线程库 有什么想法吗 谢谢。您可以使用一个事件并通过一个循环来实现TThread子体的Execute方法,该循环使用WaitForSingleObject等待事件,并指定超时时间。这样,您可以在需要时(例如终止时)立即唤醒线程。在中,您可以执行以下操

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

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

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

有什么想法吗


谢谢。

您可以使用一个事件并通过一个循环来实现
TThread
子体的
Execute
方法,该循环使用
WaitForSingleObject
等待事件,并指定超时时间。这样,您可以在需要时(例如终止时)立即唤醒线程。

在中,您可以执行以下操作:

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 dispatcher为最高优先级计时器指定适当的超时值。

使用和如果线程在应用程序的生命周期内运行,可以通过应用程序关闭时的操作系统简单地终止,并且不需要精确的计时,为什么还要麻烦使用需要比睡眠(5000)更多输入的解决方案呢?

要添加另一种实现5秒事件的方法,可以使用与TTimer类似但不依赖于您的应用程序的多媒体计时器。在配置它之后(您可以设置一个快照或重复),它会在另一个线程中调用您。就其性质而言,它非常精确(在1ms以内)。看看吧


调用计时器的代码很简单,并且在所有Windows平台上都受支持。

谢谢gabr,我想在您的论坛上向您询问这个问题,但它不起作用+1是的,域服务器出现问题;我正在努力。你能告诉我们更多你是如何实施你的计时解决方案的吗?也许写一篇关于它的博客吧?:)谢谢。我会在你的论坛上详细了解它什么时候运行。大卫,什么时候的活动?Windows事件?如果您编写自己的线程循环,那么您可以使用任何您想要的,但您也可以选择退出它,让OTL自己处理线程循环。为什么这比这里讨论的其他解决方案更好/更差?(注意,你应该改进你的答案)。因为这样你可以等待线程(程序)终止5秒。我,我只是让线程睡眠1000毫秒,然后它醒来,检查是否终止,然后检查要做的工作。该线程在系统上几乎处于空闲状态,并且工作良好且高效。当然,关闭时会有1秒的延迟,但我首先在所有线程上调用Terminate,然后执行WaitFors,因此所有线程上的总延迟是1秒,而不是1秒乘以线程计数。由于某些线程的工作时间更长,因此成本可以忽略不计。@Torbins等-如果不销毁线程,将不会调用dtor,也不会等待@gabr你当然可以等,但你为什么要等?您不想立即关闭应用程序吗?TThread.Terminate只设置了一个标志AFAIK,因此不会造成任何延迟。导致延迟的是TThread.WaitFor,可以是显式的,也可以是从TThread.Destroy调用的。如果您不调用TThread.WaitFor,您的应用程序将不会被阻止。