WMI,负CPU使用率值和过去的Timestamp_Sys100NS

wil*_*ilx 18 .net c# windows wmi

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

SELECT Timestamp_Sys100NS, PercentProcessorTime 
FROM Win32_PerfRawData_PerfOS_Processor 
WHERE Name='_Total'
Run Code Online (Sandbox Code Playgroud)

从那里我使用众所周知的公式计算CPU使用率%:

double cpu_usage = (1 - (double)delta_cpu / delta_time) * 100;
Run Code Online (Sandbox Code Playgroud)

除了一台机器(目前为止),它的效果非常好.

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

这个Windows 2003服务器是否具体?或者是超线程相关的问题?或者只是预期,我应该将CPU使用值或cpu_delta值限制在某个范围内?

编辑: 我用这台机器观察的第二个奇怪的事情是,该Timestamp_Sys100NS值并不表示FILETIME日期(自1600年1月1日以来的刻度),而是从启动时开始看起来像刻度.

编辑2:我现在已经验证了这个问题是在许多Windows 2003服务器上.而且我显然不是唯一一个有同样问题的人.

编辑3:我已经通过查询解决的时间邮票LastBootUpTimeWin32_OperatingSystem和补充说,到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);
Run Code Online (Sandbox Code Playgroud)

...然后调整到UTC ......

boot_time = boot_time.UtcDateTime;
Run Code Online (Sandbox Code Playgroud)

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

if (time.Year < 2000)
    time = boot_time + current;
Run Code Online (Sandbox Code Playgroud)

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

  1. 首先是Vista +系统,其中Timestamp_Sys100NS是UTC时代以来的时间.
  2. 其次是一些Windows 2003系统Timestamp_Sys100NS需要添加Win32_OperatingSystem.LastBootUpTime以获得合理的时间.
  3. 第三类是进行上述添加仍然导致正确日期和时间之外的日期天数的系统.

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

Ali*_*san 0

尝试在该计算机上使用代码创建应用程序,看看您是否获得正确的读数 http://www.microsoft.com/download/en/details.aspx?id=8572