4

How do I shutdown a WPF application after 'n' seconds of inactivity?

Raj
  • 4,405
  • 13
  • 59
  • 74

4 Answers4

15

A bit late, but I came up with this code, it restarts a timer on any input event:

  public partial class Window1 : Window {
    DispatcherTimer mIdle;
    private const long cIdleSeconds = 3;
    public Window1() {
      InitializeComponent();
      InputManager.Current.PreProcessInput += Idle_PreProcessInput;
      mIdle = new DispatcherTimer();
      mIdle.Interval = new TimeSpan(cIdleSeconds * 1000 * 10000);
      mIdle.IsEnabled = true;
      mIdle.Tick += Idle_Tick;
    }

    void Idle_Tick(object sender, EventArgs e) {
      this.Close();
    }

    void Idle_PreProcessInput(object sender, PreProcessInputEventArgs e) {
      mIdle.IsEnabled = false;
      mIdle.IsEnabled = true;
    }
  }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • There is one problem I found recently: When a textbox is focused and the mouse is floating over the window, the PreProcessInput-event is constantly firing. When you move the mouse outside the window or take the focus off of the textbox, it works fine. Is this me doing something wrong? – PVitt Jul 29 '10 at 09:22
  • FYI: I tried your solution and have trouble to understand exactly when the `PreProcessInput` event gets raised. You can find my question here: http://stackoverflow.com/questions/4963135/wpf-inactivity-and-activity – Martin Buberl Feb 11 '11 at 13:14
  • @Martin, I dunno, the WPF object model is far too complicated. I reckon you'll have to dig through the PreProcessInputEventArgs object and dump info to know where this is coming from. You then also have a shot at filtering it. – Hans Passant Feb 11 '11 at 13:28
  • Thanks for your quick response. That's what I'm going to do. Maybe I can figure it out. – Martin Buberl Feb 11 '11 at 13:41
1

You'll need to define "activity", but basically you want to start a timer. Then every time there is some "activity" (whether it's mouse clicks or mouse moves etc.) the timer is reset.

Then in the timer when it reaches your limit just post an event to call the application close method.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • Activities include user interaction and operation done by application in foreground/background thread. – Raj Mar 02 '10 at 12:53
  • 1
    @Raj - if you need to log operations then you might want to look at an aspect orientated approach where you fire an event on entry and exit from all operational methods which would reset the timer. – ChrisF Mar 02 '10 at 12:55
1

There was a discussion in msdn social about this matter. Check it and please post what did work for you....

I paste you the code from the discussion (the one I think it will do what you need):

public partial class Window1 : Window
{
    private EventHandler handler;
    public Window1()
    {
        InitializeComponent();

        handler = delegate
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(4);
            timer.Tick += delegate
            {
                if (timer != null)
                {
                    timer.Stop();
                    timer = null;
                    System.Windows.Interop.ComponentDispatcher.ThreadIdle -= handler;
                    MessageBox.Show("You get caught!");
                    System.Windows.Interop.ComponentDispatcher.ThreadIdle += handler;
                }

            };

            timer.Start();

            //System.Windows.Interop.ComponentDispatcher.ThreadIdle -= handler;
            Dispatcher.CurrentDispatcher.Hooks.OperationPosted += delegate
            {
                if (timer != null)
                {
                    timer.Stop();
                    timer = null;
                }
            };
        };

        ComponentDispatcher.ThreadIdle += handler;
    }
}
jmservera
  • 6,454
  • 2
  • 32
  • 45
  • 1
    ComponentDispatcher.ThreadIdle is getting fired properly, but Dispatcher.CurrentDispatcher.Hooks.OperationPosted is pumping events even if I minimize the Window that essentially stop timer. – Raj Mar 02 '10 at 13:27
0
public MainWindow()
    {
        InitializeComponent();
        var timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(10)};
        timer.Tick += delegate
        {
            timer.Stop();
            MessageBox.Show("Logoff trigger");
            timer.Start();
        };
        timer.Start();
        InputManager.Current.PostProcessInput += delegate(object s,  ProcessInputEventArgs r)
        {
            if (r.StagingItem.Input is MouseButtonEventArgs || r.StagingItem.Input is KeyEventArgs)
                timer.Interval = TimeSpan.FromSeconds(10);
        };
    }
sam
  • 151
  • 3
  • 10
  • Keep this line of code in your main window constructor or in the form load event if you want to enable auto log out event after some pre-processing. – sam Aug 26 '14 at 22:52