C#用户无效多长时间

一些背景:我正在编写一个具有多种forms的应用程序等。用户必须登录才能使用大多数function,这一直工作到现在为止。 但是,现在,客户端已请求在一定量的非活动时间之后用户将被注销。 问题是用户仍然可以在计算机上处​​于活动状态,而不是在我的应用程序中。 要清楚,我必须在用户处于非活动状态时将用户注销,即使他仍在与桌面交互。

首先我认为这很简单。 只需记住上次操作的时间,在计时器中将其与当前时间进行持续比较,如果超过允许时间,则注销用户。 但是我已经意识到找出最后一次动作时间可能并不那么简单……

当然我可以复制粘贴之类的东西

Program.LastActionTime = DateTime.Now; 

在每个OnChange,OnClick等事件中……不仅因为应用程序的大小,这将是一项大量的工作……这也是一个非常糟糕的做法,我相信它会是忘记了至少一次,使整个事情变得不可靠(并且看起来很破碎,这个bug几乎不可能重现!)

那么,有更好的方法吗?

在Program.CS文件中,您可以处理Application.Idle事件并在那里重置计时器。 看到:

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.idle.aspx

我过去使用过的一种方法是在您的申请表上创建一个MessageFilter ,并检查指示用户活动的某些类型的事件:

  public class UserActivityFilter : IMessageFilter { // Define WinAPI window message values (see pinvoke.net) private int WM_LBUTTONDOWN = 0x0201; private int WM_MBUTTONDOWN = 0x0207; private int WM_RBUTTONDOWN = 0x0204; private int WM_MOUSEWHEEL = 0x020A; private int WM_MOUSEMOVE = 0x0200; private int WM_KEYDOWN = 0x0100; public bool PreFilterMessage(ref Message m) { if (m.Msg == WM_LBUTTONDOWN || m.Msg == WM_MBUTTONDOWN || m.Msg == WM_RBUTTONDOWN || m.Msg == WM_MOUSEWHEEL || m.Msg == WM_MOUSEMOVE || m.Msg == WM_KEYDOWN) { //User activity has occurred // Reset a flag / timer etc. } return false; } } 

然后在窗体的Main()方法中,在调用Run()之前:

 Application.AddMessageFilter(new UserActivityFilter()); 

需要注意的是,添加复杂的邮件filter或添加多个单独的filter会降低应用程序的响应速度。

您可以覆盖WndProc ,在每个相关的Keyboard/Mouse事件消息上更新Program.LastActionTime

在MouseMove和KeyPressed事件上挂钩事件处理程序,然后在该事件中检查焦点?

一般来说,最好从应用程序逻辑而不是原始用户输入中获取此信息,但我认为您没有可以提供此信息的灵活基础结构(可能使用命令模式 )。

因此,我建议您只使用主窗体注册处理程序 – 如果您收到点击或关键事件(为此启用Form.KeyPreview ),您的用户将处于活动状态,您可以重置不活动时间。

您可以创建一个所有窗口窗体都inheritance自的基类。 在基类中,您可以检查并重置每个KeyPress或Click上的超时。