GetLastInputInfo的整数环绕问题

Asi*_*sik 4 .net c# int winapi

我想在我的应用程序中检查用户是否不活动.我做了一些研究,然后使用GetLastInputInfo和Environment.TickCount,因为它看起来非常简单.不幸的是,事实证明它有点敏感.

GetLastInputInfo返回一个LASTINPUTINFO结构,其最后一个"TickCount"值为DWORD(即UInt32).从理论上讲,我想从Environment.TickCount中减去该值,这样我就知道用户已经处于非活动状态的ms.

Environment.TickCount返回一个Int32.两者都会在达到最大值时回绕,这对于Int32和UInt32是不同的.我有点不舒服处理这尤其是因为基本上无法进行测试的代码(Environment.TickCount后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!
  }
}
Run Code Online (Sandbox Code Playgroud)

是否有一个简单的方法来处理这两个环绕,或者我应该使用另一种方法来完全检测用户的不活动?此外,任何关于如何测试这个没有专用计算机25天的建议表示赞赏.

Guf*_*ffa 7

由于不活动时间比蜱计数器的容量小得多,所以根本不是问题.

如果其中一个计数器已经缠绕而不是另一个,则减法中的结果也会回绕并给出正确的结果.您只需要转换值,以便它们是相同的数据类型:

int idleTime = Environment.TickCount - (int)lastInputInfo.dwTime;
Run Code Online (Sandbox Code Playgroud)

例如,如果Environment.TickCount已经回绕到-2147483612并且lastInputInfo.dwTime是2147483624,那么-2147483612 - 2147483624 = 60.

您甚至可以将两个值都转换为较小的数据类型(如Int16),只要空闲时间适合数据类型,您仍然可以在减法后获得正确的结果.