我有一个程序,偶尔需要递归地扫描一些目录(这部分程序的改进正在酝酿中,但暂时不会准备好)。为了避免用户必须等待此扫描,我希望尽可能在用户不使用我的程序时进行扫描。
我打算通过运行一个检查空闲时间的计时器来实现它。我发现以下用于检查系统空闲时间的信息: http://www.delphitips.net/2007/11/11/how-to-detect-system-idle-time/
这将是有效的,但我更愿意激活该功能,即使用户正在同一台计算机上使用其他程序。这样,如果他切换到另一个程序,我就可以 catch 我需要做的扫描。
我意识到我可以在后台线程中进行扫描,并且该扫描或某种 Windows Hook 将在某个时候实现,但不是现在。
编辑: 这里的目标是对程序进行相对简单的更改,以在用户未主动使用“我的应用程序”时执行可能排队的任何扫描。扫描并不是特别密集,但它不是在线程中完成的,因此在进行过程中会卡住我的应用程序。基本上,我在寻找更长期的解决方案时寻求快速获胜。
最佳答案
使用Application.OnIdle
事件。当您的程序没有更多窗口消息需要处理时,会触发该事件。键盘和鼠标都会生成消息,因此如果没有更多消息,则用户不会使用您的程序,即使它具有焦点。
procedure TJasonForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
var
NoMoreFiles: Boolean;
begin
// TODO: Scan for the next file
Done := NoMoreFiles;
end;
只要 Done
为 False 并且队列中没有消息,您的程序将继续调用该事件处理程序,从而允许您查找更多文件。当用户生成一些输入时,您的程序将在再次调用 OnIdle
之前处理这些消息。
扫描完文件系统后,将 Done
设置为 True,以便程序停止重新调用 OnIdle
处理程序。如果您忽略这样做,那么您的程序将使用所有可用的 CPU 时间重复调用不执行任何操作的事件处理程序。
要实现此功能,您需要使用非递归搜索例程。递归搜索将在返回之前搜索整个文件系统,但如果您这样做,则 OnIdle 处理程序将挂起您的程序,这与您想要的相反。您可以使用目录名称队列,每次触发事件时,从队列中弹出一项,搜索它,并将其内容添加到队列末尾。
关于delphi - 如何检查程序空闲时间而不是系统空闲时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6126141/