I want to check for user inactivity in my application. I did a little bit of research and went for using GetLastInputInfo and Environment.TickCount because it seemed very simple. Unfortunately it turns out to be a little bit touchy.
GetLastInputInfo returns a LASTINPUTINFO structure which has the last "TickCount" value as a DWORD (i.e. UInt32). In theory, I want to substract that value from Environment.TickCount and that gives me for how many ms the user has been inactive.
Environment.TickCount returns an Int32. Both will wrap around when they hit their max value, which is different for an Int32 and a UInt32. I'm a little uncomfortable dealing with this especially since the code essentially can't be tested (Environment.TickCount wraps around after 24.9 days and the feature is due before that).
Here's what I've done so far:
[DllImport("user32.dll")]
static extern bool GetLastInputInfo(out LastInputInfo plii);
struct LastInputInfo
{
public uint cbSize;
public uint dwTime;
}
//(...)
var lastInputInfo = new LastInputInfo();
lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
if (GetLastInputInfo(out lastInputInfo))
{
// The next line obviously will not work when either of the terms has wrapped around
var idleTime = Environment.TickCount - lastInputInfo.dwTime;
if (idleTime > mTimeOut)
{
// user is inactive!
}
}
Is there a simple enough way to deal with both wrap-arounds or should I use another approach to detect user inactivity altogether? Also any advice on how to test this without dedicating a computer for 25 days is appreciated.
As the period of inactivity is considerably smaller than the capacity of the tick counters, it's not a problem at all.
If one of the counters have wrapped around and not the other, the result in your subtraction will also wrap around and give you the correct result. You just have to cast the values so that the are the same data type:
int idleTime = Environment.TickCount - (int)lastInputInfo.dwTime;
If for example Environment.TickCount
has wrapped around to -2147483612 and lastInputInfo.dwTime is 2147483624, then -2147483612 - 2147483624 = 60.
You could even cast both values down to a smaller data type, like Int16, and you would still get the correct result after the subtraction as long as the idle time fits in the data type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With