4

我正在做一个 delphi 应用程序,它将在我的 pc 上 24/7 在后台运行,并检查它是否必须执行某些操作,等待 30 分钟并再次检查,依此类推。

如何确保应用程序不会因为一直在运行而使 CPU 或内存过载。

4

7 回答 7

14

创建一个每 30 分钟运行一次的计时器,然后从那里调用您的检查/操作。然后,您的应用程序可以在无事可做时闲置。

或者,您可以创建一个定期运行的计划任务来执行此操作。

于 2010-05-13T19:19:42.003 回答
5

关于计时器的答案是很好的解决方案,我补充说:确保计时器事件或调用的后续过程检查忙。即,如果您醒来,请确保在开始新批次之前完成最后一批。当事情进展顺利时很容易错过这一点,然后您会遇到这样的情况:事情被备份并且整个系统在早上 8 点卡住,因为在午夜发生了一些不好的事情,现在有 16 个调用堆叠(或线程、流程等)。

所以写你的定时器事件是这样的:

OnMyTimer...
begin
  MyTimer.Enabled := false;
  try
    DoSomethingForALongTime;  // Usually runs in 45 seconds, but sometimes takes 45 minutes!
  finally
    MyTimer.Enabled := true;  // and (SomeAbortRequest = False) and (SomeHorribleErrorCount = 0);  
  end;
end;
于 2010-05-13T19:41:04.620 回答
1

The answers about timers are pretty much exactly what you're looking for. As for your question about not overloading the CPU or memory, take a look at your program in the Task Manager. When it's not doing anything, it should sit at a "steady state" of memory, not allocating any more, and using 1% or less of CPU time.

It's safe to let most programs idle for long periods. The VCL knows how to handle the idling without hogging CPU resources for you, and you just need to use a timer to make sure it wakes up and activates its event at the right time.

于 2010-05-13T19:26:08.463 回答
0

大多数编程语言都有一个“睡眠”功能,你可以调用它来让程序停止做事。

您可以控制内存使用;你可以在睡觉前释放你的内存并在醒来时重新分配它,但是......

设置一些经常性的工作可能会更好。我不知道该怎么做,但我怀疑 Windows Scripting Host 有一种方法可以按照您想要的任何时间表启动您的应用程序。

于 2010-05-13T19:17:35.190 回答
0

您没有说出来,但是如果您的应用程序使用多个线程,这可能会增加操作系统在您的进程上花费的 CPU 量(例如读取时间片和线程切换)。

操作系统也可能会换出一些内存页面,因此在“等待时间”中使用更少的内存和/或减少内存访问也有帮助。

因此,如果您只使用一个线程并且也没有额外的消息循环,那么只需调用 Sleep() 可能是一种好方法,因为这将向操作系统发出信号,表明您在很长一段时间内根本不需要时间片来来。

避免 YieldThread()/SwitchToThread() 和你自己的计时(例如使用 Now()),因为这意味着很多线程切换正在发生,做......什么都不做!

另一种方法可能是使用具有较大超时的WaitForMultipleObjects,这样您的应用程序仍然可以响应消息。

于 2010-05-17T08:28:48.613 回答
0

如果您想强制执行绝对不活动状态,我想您可以使用“睡眠”功能。虽然我不确定它在重新启动时会如何表现。(我猜 Windows 会报告应用程序没有响应。)

如果应用程序没有主窗体并且只是坐在托盘中(或完全不可见),它不会做太多事情。主消息循环将处理它从操作系统接收到的所有消息,但它不应该收到很多消息。并且它将收到的少数消息,它应该处理它们(关闭消息,系统参数更改通知等)

所以,我认为你可以只设置一个计时器而忘记设置代码来强制你的程序保持空闲。

如果您真的想将该进程活动限制为最大值,则可以在进入/离开计时器事件时设置线程优先级。因此,您可以在进入事件时将优先级设置为“正常”,并在退出事件时将其设置为“低”。

于 2010-05-13T19:46:38.417 回答
0

我建议创建一个服务应用程序(将启动类型设置为自动)并使用 CreateTimerQueueTimer 作为您的计时器。可以通过保留内存需求/池类来缓解内存泄漏。

于 2010-05-26T12:05:44.100 回答