一些背景: 我正在编写一个包含多种表单等的应用程序。用户必须登录才能使用大部分功能,并且直到现在都运行良好。但是,现在,客户端要求用户在一定的非事件时间后注销。问题是用户仍然可以在计算机上处于事件状态,只是不在我的应用程序中。明确地说,当用户在我的应用程序中处于非事件状态时,我必须将其注销,即使他仍在与桌面交互也是如此。
起初我认为这会相当简单。只需记住上次操作的时间,在计时器中不断将其与当前时间进行比较,如果耗时大于允许的时间,则注销用户。但是我意识到找出最后一个 Action 时间可能不是那么简单......
当然我可以复制粘贴类似的东西
Program.LastActionTime = DateTime.Now;
在每个 OnChange、OnClick 等事件中……但是,由于应用程序的大小,这不仅会带来大量工作……这也是一个非常糟糕的做法,我敢肯定它至少会被遗忘一次,从而使整个事情变得不可靠(而且看起来很糟糕,这个错误几乎不可能重现!)
那么,有没有更好的办法呢?
最佳答案
我过去使用的一种方法是创建一个 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());
请注意,添加复杂的消息过滤器或添加多个单独的过滤器会降低应用程序的响应速度。
关于C# 用户不活动多长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1421403/