C# как долго пользователь был неактивен
некоторые предпосылки: Я пишу приложение с несколькими формами и т. д. Пользователи должны войти в систему, чтобы использовать большинство функций, и это работало нормально до сих пор. Однако теперь клиент запросил, чтобы пользователь вышел из системы через определенное количество неактивного времени. Проблема в том, что пользователь все еще может быть активен на компьютере, просто не в моем приложении. Чтобы быть ясным, я должен выйти из системы, когда он неактивен в моем приложении, даже если он все еще взаимодействует с рабочий стол.
сначала я думал, что это будет довольно простой. Просто запомните время последнего действия, сравните его постоянно в таймере с текущим временем и выйдите из системы, если прошедшее время больше допустимого. Однако я понял, что выяснить время последнего действия может быть не так просто...
конечно, я мог бы скопировать вставить что-то вроде
Program.LastActionTime = DateTime.Now;
в каждом onChange, после чего, на кнопке и т. д., событие ... Однако не только это было бы a большой объем работы из-за размера приложения ... Это также было бы очень плохой практикой, и я уверен, что это будет забыто хотя бы один раз, что делает все это ненадежным (и кажется сломанным, ошибка будет почти невозможно воспроизвести!)
Итак, есть ли лучший способ?
6 ответов
в вашей программе.CS файл, вы можете обрабатывать приложение.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());
одно предостережение, добавление сложного фильтра сообщений или добавление нескольких отдельных фильтров может замедлить отзывчивость вашего приложения.
можно переопределить WndProc
, update Program.LastActionTime
на каждой соответствующей Keyboard/Mouse
сообщение о событии.
подключите обработчик событий к событиям MouseMove и KeyPressed, а затем проверьте фокус внутри этого события?
в целом было бы лучше всего получить эту информацию из вашей логики приложения вместо raw-ввода пользователя, но я предполагаю, что у вас нет гибкой инфраструктуры (возможно, используя команда), которые могли бы предоставить эту информацию.
поэтому я предлагаю просто зарегистрировать обработчики с вашей основной формой - если вы получаете клики или ключевые события (enable форма.KeyPreview для этого), ваш пользователь активен, и вы можете сбросить время бездействия.
вы можете создать базовый класс, от которого наследуются все ваши оконные формы. В базовом классе вы проверяете и сбрасываете тайм-аут при каждом нажатии клавиши или щелчке.