我想在一段时间不活动后将用户从我的应用程序中注销。
将我的不活动检查放在应用程序的 OnIdle 处理程序或计时器处理程序中会更好吗?
粒度不是太重要。注销可能会增加/减少几秒钟,甚至可能是一分钟。
我感觉应用程序的 OnIdle 会频繁触发。有什么建议吗?代码本身只有几行。
我想在一段时间不活动后将用户从我的应用程序中注销。
将我的不活动检查放在应用程序的 OnIdle 处理程序或计时器处理程序中会更好吗?
粒度不是太重要。注销可能会增加/减少几秒钟,甚至可能是一分钟。
我感觉应用程序的 OnIdle 会频繁触发。有什么建议吗?代码本身只有几行。
您正在使用 GetLastInputInfo 来测量空闲时间。这似乎非常明智。所以问题归结为
我应该在 OnIdle 处理程序或计时器中进行定期检查吗?
每次清空消息队列时都会触发 OnIdle。如果队列中没有任何消息,OnIdle 将永远不会触发。所以,OnIdle 不是周期性的。如果您想定期检查不活动状态,那么 OnIdle 可能不起作用。计时器肯定会工作。
你可以这样想:OnIdle 事件在空闲计数器启动时触发,但您需要在空闲计数器过期时触发一个事件。
我感觉应用程序的 OnIdle 会频繁触发。
其实你的问题正好相反!
请注意,您可以对此进行试验并发现 OnIdle 似乎可以正常工作,并且会定期触发。例如,如果您的应用程序使用任何计时器,则 OnIdle 将在每个计时器事件之后触发。因为计时器事件进入队列,一旦处理完毕,就会触发 OnIdle。但是,如果您的应用程序没有计时器,那么如果您停止与程序交互,您可以期望 OnIdle 根本不会触发。
我个人使用以下内容。
GetLastInputInfo 来自 Windows,并给出一个结果,说明多久没有键盘或鼠标活动..
TimerLogoffTimer 是设置为每 5 秒触发一次的定时器
TimeoutValue 是我从配置中读取的值
DoLogoff 是执行关闭表单等实际工作的程序。
function SecondsIdle: DWord;
var
liInfo: TLastInputInfo;
begin
liInfo.cbSize := SizeOf(TLastInputInfo) ;
GetLastInputInfo(liInfo) ;
Result := (GetTickCount - liInfo.dwTime) DIV 1000;
end;
procedure TfrmMain.TimerLogoffTimer(Sender: TObject);
begin
if SecondsIdle >= DWord(TimeoutValue) then
DoLogoff;
end;
前几天在 Embarcadero 论坛上讨论了 OnIdle 与 TTimer 的问题:
特别是,我在那次讨论中的回复解释了TApplication.OnIdle
事件的实际工作方式,以及设置Done
参数的实际含义:
我知道 OnIdle 仅在应用程序开始空闲时被调用一次。
每次应用程序进入新的空闲状态时都会调用它。每次主消息循环从主消息队列中检索消息并且还没有消息时,都会触发 OnIdle 事件并且主线程进入睡眠状态,直到有新消息到达队列。一旦消息被处理并且队列再次变空,OnIdle 事件被再次触发并且主线程休眠直到有新消息到达,等等。
如果我使用它,我的检查程序只会被调用一次,然后系统将继续等待用户输入而不再次检查。
在 OnIdle 事件处理程序中,您可以将 Done 参数设置为 False 以防止主线程在没有要处理的消息时进入其睡眠状态。这将允许 OnIdle 事件在队列中没有新消息时继续被触发。但是,这会产生禁用 TAction.OnUpdate 事件的副作用。
我想要做的是更新计时器的显示。
然后,您应该使用真正的计时器广告在每次计时器结束时更新 UI。
随着剩余时间的变化,它需要不断地重新绘制自己。也许还有另一种更简单/更好的简单方法可以做到这一点。
查看 TTimer 组件及其 OnTimer 事件。
为什么不让 Windows 为您执行此操作?
当用户想要重新开始工作时,有一些策略会自动启动屏幕保护程序并强制登录。
从 Windows 7 开始,您无法使用咖啡因或其他键盘模拟器等工具来解决它们。
这使得它比您在 Delphi 应用程序中可以做的任何事情都要严格得多。
TTimer 使用 Windows 内部资源,这在当今千兆赫和千兆字节的世界中可能没什么大不了的,但仍然不是很好。
我会尝试使用 OnIdle 或 MainForm.Action - http://docwiki.embarcadero.com/Libraries/en/System.Classes.TBasicAction.OnUpdate
这两种方法可能都需要稍微降低 - http://docwiki.embarcadero.com/Libraries/en/Vcl.Forms.TApplication.ActionUpdateDelay
请注意关于 TApplication.OnIdle 的那些行 - 这可能是在每个循环之后将 stup no-op 消息发布到应用程序的自链接事件:
除非 Done 参数设置为 false,否则不会连续调用它。将 Done 设置为 false 的应用程序会消耗过多的 CPU 时间,这会影响整体系统性能。