Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# GetLastInputInfo的整数环绕问题_C#_.net_Winapi_Int - Fatal编程技术网

C# GetLastInputInfo的整数环绕问题

C# GetLastInputInfo的整数环绕问题,c#,.net,winapi,int,C#,.net,Winapi,Int,我想检查应用程序中的用户是否处于非活动状态。我做了一些研究,并选择使用GetLastInputInfo和Environment.TickCount,因为它看起来非常简单。不幸的是,结果有点敏感 GetLastInputInfo返回最后一个“TickCount”值为DWORD的结构(即UInt32)。理论上,我想从Environment.TickCount中减去该值,这就给出了用户处于非活动状态的毫秒数 返回一个Int32。当它们达到最大值时,两者都会环绕,这对于Int32和UInt32是不同的。

我想检查应用程序中的用户是否处于非活动状态。我做了一些研究,并选择使用GetLastInputInfo和Environment.TickCount,因为它看起来非常简单。不幸的是,结果有点敏感

GetLastInputInfo返回最后一个“TickCount”值为DWORD的结构(即UInt32)。理论上,我想从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,只要空闲时间适合该数据类型,减法后仍然可以得到正确的结果。

这只是Guffa答案的补充

在依赖整数溢出时,始终使用未选中的
关键字是“最佳实践”。原因有两个:

  • 它让读者知道您有意依赖溢出
  • 虽然未选中是C#中的默认值,但这可以在编译器的命令行上更改

  • 这看起来是正确的,我在F#interactive中做了一些测试来验证:P谢谢!为了确认,假设您使用Win32 GetTickCount()返回uint,结果将是正确的?如果系统正常运行时间达到49.7天,并且最后一次用户交互发生在Environment.TickCount结束之前,只要用户空闲,就没有办法获得空闲时间?请记住,这种方法只能检测到以50天为单位的用户不活动时间。@HristoIliev感谢提醒,但此功能的用例是5分钟-1小时不活动,因此这不是问题。+1是的,这使代码更具信息性,而且更健壮,不依赖于特定的编译器设置。
    int idleTime = unchecked(Environment.TickCount - (int)lastInputInfo.dwTime);