5

我想在一段时间不活动后将用户从我的应用程序中注销。

将我的不活动检查放在应用程序的 OnIdle 处理程序或计时器处理程序中会更好吗?

粒度不是太重要。注销可能会增加/减少几秒钟,甚至可能是一分钟。

我感觉应用程序的 OnIdle 会频繁触发。有什么建议吗?代码本身只有几行。

4

5 回答 5

9

您正在使用 GetLastInputInfo 来测量空闲时间。这似乎非常明智。所以问题归结为

我应该在 OnIdle 处理程序或计时器中进行定期检查吗?

每次清空消息队列时都会触发 OnIdle。如果队列中没有任何消息,OnIdle 将永远不会触发。所以,OnIdle 不是周期性的。如果您想定期检查不活动状态,那么 OnIdle 可能不起作用。计时器肯定会工作。

你可以这样想:OnIdle 事件在空闲计数器启动时触发,但您需要在空闲计数器过期时触发一个事件。

我感觉应用程序的 OnIdle 会频繁触发。

其实你的问题正好相反!


请注意,您可以对此进行试验并发现 OnIdle 似乎可以正常工作,并且会定期触发。例如,如果您的应用程序使用任何计时器,则 OnIdle 将在每个计时器事件之后触发。因为计时器事件进入队列,一旦处理完毕,就会触发 OnIdle。但是,如果您的应用程序没有计时器,那么如果您停止与程序交互,您可以期望 OnIdle 根本不会触发。

于 2012-10-04T06:10:28.020 回答
7

我个人使用以下内容。

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;
于 2012-10-04T05:36:51.160 回答
2

前几天在 Embarcadero 论坛上讨论了 OnIdle 与 TTimer 的问题:

事件处理问题

特别是,我在那次讨论中的回复解释了TApplication.OnIdle事件的实际工作方式,以及设置Done参数的实际含义:

我知道 OnIdle 仅在应用程序开始空闲时被调用一次。

每次应用程序进入新的空闲状态时都会调用它。每次主消息循环从主消息队列中检索消息并且还没有消息时,都会触发 OnIdle 事件并且主线程进入睡眠状态,直到有新消息到达队列。一旦消息被处理并且队列再次变空,OnIdle 事件被再次触发并且主线程休眠直到有新消息到达,等等。

如果我使用它,我的检查程序只会被调用一次,然后系统将继续等待用户输入而不再次检查。

在 OnIdle 事件处理程序中,您可以将 Done 参数设置为 False 以防止主线程在没有要处理的消息时进入其睡眠状态。这将允许 OnIdle 事件在队列中没有新消息时继续被触发。但是,这会产生禁用 TAction.OnUpdate 事件的副作用。

我想要做的是更新计时器的显示。

然后,您应该使用真正的计时器广告在每次计时器结束时更新 UI。

随着剩余时间的变化,它需要不断地重新绘制自己。也许还有另一种更简单/更好的简单方法可以做到这一点。

查看 TTimer 组件及其 OnTimer 事件。

于 2012-10-04T21:49:49.337 回答
1

为什么不让 Windows 为您执行此操作?

当用户想要重新开始工作时,有一些策略会自动启动屏幕保护程序并强制登录。

从 Windows 7 开始,您无法使用咖啡因或其他键盘模拟器等工具来解决它们。

这使得它比您在 Delphi 应用程序中可以做的任何事情都要严格得多。

于 2012-10-04T04:04:54.003 回答
0

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 时间,这会影响整体系统性能。

于 2012-10-04T06:29:17.883 回答