c# - 过去的 WMI、负 CPU 使用率值和 Timestamp_Sys100NS

标签 c# .net windows wmi

我正在使用 WMI 监控一些机器,使用 .NET 的 System.Management 东西。我正在使用的查询是这样的:

SELECT Timestamp_Sys100NS, PercentProcessorTime 
FROM Win32_PerfRawData_PerfOS_Processor 
WHERE Name='_Total'

据此,我使用众所周知的公式计算 CPU 使用率百分比:

double cpu_usage = (1 - (double)delta_cpu / delta_time) * 100;

除了一台(到目前为止),它在每台机器上都运行良好。

问题是对于一台机器,它是 Windows 2003 服务器(启用了超线程,如果重要的话),我有时会得到负的 CPU 使用率值。换句话说,(double)delta_cpu/delta_time 表达式产生数字 > 1。我确实在网上搜索了关于为什么会发生这种情况的提示,但我一无所获。

这个 Windows 2003 服务器是特定的吗?还是与超线程相关的问题?或者它只是预期的,我应该将 CPU 使用率值或 cpu_delta 值限制在某个范围内?

编辑: 我在这台机器上观察到的第二个奇怪的事情是 Timestamp_Sys100NS 值并不表示 FILETIME 之类的日期(自纪元 1600 年 1 月 1 日开始计时),而是它看起来像自启动时间以来的滴答声。

编辑 2: 我现在已经证实这个问题存在于很多 Windows 2003 服务器上。我显然是not the only one with the same problem .

编辑 3: 我通过从 Win32_OperatingSystem 查询 LastBootUpTime 并将其添加到 Timestamp_Sys100NS 来解决时间戳问题,当 Timestamp_Sys100NS 过去太远了。这似乎给出了正确的日期和时间。从 Win32_OperatingSystem 检索日期后处理日期的代码如下所示:

WbemScripting.SWbemDateTime swbem_time = new WbemScripting.SWbemDateTime();
swbem_time.Value = date_str;
string time_as_file_time_str = swbem_time.GetFileTime(true);
return new DateTimeOffset(epoch.Ticks + long.Parse(time_as_file_time_str),
    swbem_time.UTCSpecified
    ? TimeSpan.FromMinutes(swbem_time.UTC)
    : TimeSpan.Zero);

...然后调整为 UTC...

boot_time = boot_time.UtcDateTime;

...然后 boot_time 简单地添加到 WMI 在 Timestamp_Sys100NS 字段中返回的时间戳(current)...

if (time.Year < 2000)
    time = boot_time + current;

编辑 4: 关于 Timestamp_Sys100NS,似乎有 3 类系统:

  1. 首先是 Vista+ 系统,其中 Timestamp_Sys100NS 是自 UTC 纪元以来的滴答时间。
  2. 其次是某些 Windows 2003 系统,需要将 Timestamp_Sys100NS 添加到 Win32_OperatingSystem.LastBootUpTime 以获得合理的时间。
  3. 第三类是在执行上述添加后仍会导致日期与正确日期和时间相差几天的系统。

编辑 5:一些受影响的机器可能是虚拟机,但不是全部。

最佳答案

对我来说这听起来像是一个标准的“时间同步”问题。

你的系统时钟是……一个时钟。在你的情况下,你的时钟可能运行得很快(也许它在实际时间的 99% 内完成一分钟)所以当你的计算机与外部时钟同步时(例如通过 Windows 时间服务)你的系统时间将向后跳。

或者,用户可以手动调整系统时间(例如:日期和时间控制面板),所以这是您应该设计的东西(如果设置他们的系统时间会使您的应用程序崩溃,您的用户会非常不高兴!)

我解决这个问题的方法是夹紧。始终需要至少 0.0 秒的“实时”时间才能通过,但也要限制在最多 0.5 秒,因为时间调整可能会向前跳跃,而不仅仅是向后跳跃。

希望对您有所帮助。

关于c# - 过去的 WMI、负 CPU 使用率值和 Timestamp_Sys100NS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8267981/

相关文章:

c# - 我可以简化这段代码吗?如果是这样的话

C# LINQ 选择具有多个值的属性的列表

c# - 保持单个连接还是仅在需要更改某些内容时才打开?

c# - 为什么不允许在 .NET 中就地实现接口(interface)?

c++ - 使用 SendInput 函数模拟输入

windows - 构建时部署所有 Qt 依赖项

c# - 如何在 WinForms 的 ComboBox 中居中对齐所选项目?

c# - ServiceStack 中的索引输入

c# - 如何以编程方式从 web.config 的属性 "maxAllowedContentLength"中获取值?

java - 禁用 JAVA 中的所有键和组合键