2009-09-14 10 views
9

Einige Hintergrund: Ich schreibe eine Anwendung mit mehreren Formen, usw. Benutzer müssen sich anmelden, um die meisten Funktionen zu verwenden, und das hat bis jetzt gut funktioniert. Jetzt hat der Client jedoch angefordert, dass der Benutzer nach einer bestimmten Inaktivitätszeit abgemeldet wird. Das Problem ist, dass der Benutzer immer noch auf dem Computer aktiv sein kann, nur nicht in meiner Anwendung. Um klar zu sein, muss ich den Benutzer ausloggen, wenn er in meiner Anwendung inaktiv ist, selbst wenn er noch mit dem Desktop interagiert.C# Wie lange war der Benutzer inaktiv

Zuerst dachte ich, das wäre ziemlich einfach. Merken Sie sich einfach die Zeit der letzten Aktion, vergleichen Sie sie kontinuierlich in einem Timer mit der aktuellen Uhrzeit und melden Sie den Benutzer ab, wenn die verstrichene Zeit größer als die erlaubte Zeit ist. Ich habe jedoch festgestellt, dass die letzte Aktion Zeit herauszufinden, ist nicht so einfach sein kann ...

Natürlich habe ich Paste etwas wie

Program.LastActionTime = DateTime.Now; 

in jedem OnChange, OnClick, etc kopieren könnte, Event ... Aber nicht nur, dass dies wegen der Größe der Anwendung eine große Menge an Arbeit wäre ... Es wäre auch eine sehr schlechte Übung und ich bin sicher, dass es mindestens einmal vergessen würde, was das Ganze unzuverlässig machen würde (Und gebrochen erscheinen, wäre der Fehler fast unmöglich zu reproduzieren!)

Also, gibt es einen besseren Weg?

Antwort

0

Einen Ereignishandler für die MouseMove- und KeyPressed-Ereignisse einhängen und dann nach dem Fokus in diesem Ereignis suchen?

0

Im Allgemeinen wäre es die beste Idee, diese Informationen aus Ihrer Anwendungslogik anstelle von rohen Benutzereingaben abzuleiten, aber ich nehme an, Sie haben keine flexible Infrastruktur (möglicherweise unter Verwendung der command pattern), die diese Informationen bereitstellen könnte.

Ich schlage vor, nur Handler mit Ihrem Hauptformular zu registrieren - wenn Sie Klicks oder Schlüsselereignisse erhalten (aktivieren Sie Form.KeyPreview für diese), ist Ihr Benutzer aktiv und Sie können die Inaktivitätszeit zurücksetzen.

0

Sie könnten eine Basisklasse erstellen, von der alle Ihre Fensterformen erben. In der Basisklasse überprüfen und setzen Sie das Timeout bei jedem Tastendruck oder Klick zurück.

6

Ein Ansatz, den ich in der Vergangenheit verwendet habe, einen MessageFilter auf Ihrem Antragsformular erstellen und für bestimmte Arten von Ereignissen überprüfen, die Benutzeraktivität anzeigen:

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; 
     } 
    } 

Dann in dem Main() -Methode der bilden, bevor der Anruf starten():

Application.AddMessageFilter(new UserActivityFilter()); 

eine Einschränkung, das Hinzufügen einer komplexen Nachrichtenfilter oder das Hinzufügen von mehreren separaten Filter, um die Reaktionsfähigkeit Ihrer Anwendung verlangsamen kann.

1

können Sie WndProc außer Kraft setzen, aktualisieren Program.LastActionTime auf jede relevante Keyboard/Mouse Ereignismeldung.

Verwandte Themen