2009-09-14 16 views
9

Alcuni background: Sto scrivendo un'applicazione con diversi moduli, ecc. Gli utenti devono effettuare il login per poter utilizzare la maggior parte delle funzionalità, e questo ha funzionato fino ad ora. Tuttavia, ora, il client ha richiesto che l'utente venga disconnesso dopo una certa quantità di tempo inattivo. Il problema è che l'utente può essere ancora attivo sul computer, ma non nella mia applicazione. Per essere chiari, devo disconnettere l'utente quando è inattivo nella mia applicazione, anche se sta ancora interagendo con il desktop.C# Per quanto tempo l'utente era inattivo

primo momento ho pensato che questo sarebbe abbastanza semplice. Basta ricordare l'ora dell'ultima azione, confrontarla continuamente in un timer con l'ora corrente e disconnettere l'utente se il tempo trascorso è maggiore del tempo consentito. Comunque ho capito che scoprire l'ultima volta che l'azione potrebbe non essere così semplice ...

Naturalmente potrei copia incolla qualcosa come

Program.LastActionTime = DateTime.Now; 

in ogni OnChange, OnClick, ecc, evento ... Tuttavia, non solo questa sarebbe una grande quantità di lavoro a causa delle dimensioni dell'applicazione ... Sarebbe anche una pessima pratica e sono sicuro che sarebbe stata dimenticata almeno una volta, rendendo l'intera cosa inaffidabile (E appare rotto, il bug sarebbe quasi impossibile da riprodurre!)

Quindi, c'è un modo migliore?

risposta

0

Hook un gestore di eventi sugli eventi MouseMove e keyPressed, e quindi controllare per il fuoco all'interno di quell'evento?

0

In generale, sarebbe meglio ricavare queste informazioni dalla logica dell'applicazione anziché dall'input dell'utente grezzo, ma presumo che non si disponga di un'infrastruttura flessibile (magari utilizzando lo command pattern) che potrebbe fornire queste informazioni.

quindi suggerisco solo per registrare i gestori con il modulo principale - se si riceve clic o eventi chiave (abilitare Form.KeyPreview per questo), l'utente è attivo ed è possibile resettare il tempo di inattività.

0

si potrebbe creare una classe di base che tutti i moduli Window eredita dalla. Nella classe base controlli e resetta il tuo timeout su ogni KeyPress o Click.

6

Un approccio che ho usato in passato, creare un MessageFilter sul modulo di domanda e verificare la presenza di alcuni tipi di eventi che indicano l'attività dell'utente:

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

Poi nel metodo Main() della formare, prima della chiamata a run():

Application.AddMessageFilter(new UserActivityFilter()); 

un avvertimento, l'aggiunta di un filtro dei messaggi complessi o aggiungere più filtri separati può rallentare i tempi di risposta dell'applicazione.

1

È possibile eseguire l'override di WndProc, aggiornare Program.LastActionTime in ciascun messaggio di evento relativo a Keyboard/Mouse.

Problemi correlati