SYSK 160: Implementing Session Expiration Concept in WinForms


If you’re writing an application that displays sensitive data (i.e. must be very secure), or you’re working on an application run by multiple users sharing a windows login (yes, it still happens), you may want to implement a “Session Expiration” concept borrowed from the web world.  In other words, if a user has not been using the application (i.e. no mouse/keyboard activity) for X minutes, then require some kind of authentication (pin, employee id, login password, etc.)


 


How would you implement it?  WinForms fires Application.Idle event fires every time the application goes idle, i.e. when all messages in the application message queue have finished processing.  Note:  it does not fire again until the application has done something and then goes idle again.  So, in Application.Idle handler, start/restart a timer that will “wake up” your locking code (e.g. display a modal login form) in X minutes…    


 


Important:  Because Application.Idle is a static event, you must detach any event handlers attached to this event in the ApplicationExit event. If you do not detach these handlers, they will remain attached to the event and continue to consume memory.


 


 

Comments (3)

  1. Herr Cann says:

    Hi Irena, thanks for your tip, I didn’t know about the Application.Idle event. Just for the feature to be complete, the post is missing where to Stop the timer when the user returns to use the application. i.e. I have a "session timeout" or 10 minutes, and I am idle for 3 minutes (the timer has already been started in the Application.Idle event) but then I come back from the limbo and start working. Where do I notify the timer "hey buddy! stop! the user has come back!".

    I would answer that, but I haven’t found any Application.IdleNoMore hehe.

  2. irenake says:

    Herr,

    My thinking was that you would reset the timer in the Application.Idle event handler (see code below).  However, this approach would only work if your application does not have the focus.  For a more comprehensive solution you’d have to also watch for keyboard and mouse events, and, optionally, any threads created by the app and running a long operation, etc.

    **************************

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Text;

    using System.Windows.Forms;

    namespace WindowsApplication2

    {

       public partial class Form1 : Form

       {

           Timer _timeout;

           public Form1()

           {

               InitializeComponent();

           }

           private void Form1_Load(object sender, EventArgs e)

           {            

               Application.Idle += new EventHandler(Application_Idle);            

           }

           void Application_Idle(object sender, EventArgs e)

           {

               System.Diagnostics.Debug.WriteLine(string.Format("Application_Idle: {0}", DateTime.Now.ToString("hh:MM:ss.ms")));

               if (_timeout == null)

               {

                   _timeout = new Timer();

                   _timeout.Interval = 30000;  // 30 sec

                   _timeout.Enabled = true;

                   _timeout.Tick += new EventHandler(Timeout_Expired);

               }          

               _timeout.Stop();

               _timeout.Start();

           }

           void Timeout_Expired(object sender, EventArgs e)

           {

               // TODO: lock the form and display login screen

               MessageBox.Show("Login screen");

           }

       }

    }

  3. Sridharan says:

    Hi…

    I am trying to implement this to provide an autosave option in my application. Everything works fine except when the focus is on a textbox control, the blink makes the timer to reset.. how to tackle this..

    Thank you