我想检查我的应用程序中是否有用户不活动。我做了一点研究,选择使用getlastinputinfo和environment.tickcount,因为它看起来非常简单。不幸的是结果有点敏感。
getLastInputinfo返回一个LASTINPUTINFO结构,该结构的最后一个“tickCount”值是一个双字(即uint32)。理论上,我想从environment.tickcount中减去这个值,这就给出了用户处于非活动状态的毫秒数。
environment.tickCount返回Int32。两者都将在达到最大值时环绕,这对于int32和uint32是不同的。处理这个问题我有点不舒服,特别是因为代码本质上是无法测试的(environment.tickcount在24.9天后结束,而这个特性在24.9天后到期)。
我到目前为止所做的是:
[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!
}
}
有没有足够简单的方法来处理这两个包装,或者我应该使用另一种方法来检测用户的不活动?另外,对于如何在25天内不使用计算机进行测试的任何建议,我们都将不胜感激。
最佳答案
由于不活动的时间比计时计数器的容量小得多,这根本不是问题。
如果其中一个计数器已环绕而不是另一个,则减法中的结果也将环绕并给出正确的结果。您只需强制转换这些值,以便它们是相同的数据类型:
int idleTime = Environment.TickCount - (int)lastInputInfo.dwTime;
例如,如果
Environment.TickCount
已包装到-2147483612,而lastinputinfo.dwtime为2147483624,则-2147483612-2147483624=60。您甚至可以将这两个值都转换为更小的数据类型,如int16,并且只要空闲时间适合该数据类型,在减法之后仍然可以得到正确的结果。