5

当我遇到这个奇怪的问题时,我试图弄清楚为什么某些性能计数器没有在我们的生产服务器中更新 - 计数器RawValue在不是只读时似乎返回不同的值。只读时始终为零,非只读时显示不同的值。

这是我的 PowerShell 会话,显示了这一点:

PS C:\Users\doron> $counter = new-object Diagnostics.PerformanceCounter
PS C:\Users\doron> $counter.CategoryName = "My category"
PS C:\Users\doron> $counter.CounterName = "My counter name"
PS C:\Users\doron> $counter.ReadOnly = 1
PS C:\Users\doron> $counter


CategoryName     : My category
CounterHelp      : My counter name
CounterName      : My counter name
CounterType      : NumberOfItems64
InstanceLifetime : Global
InstanceName     :
ReadOnly         : True
MachineName      : .
RawValue         : 0
Site             :
Container        :



PS C:\Users\doron> $counter.ReadOnly = 0
PS C:\Users\doron> $counter


CategoryName     : My category
CounterHelp      : My counter name
CounterName      : My counter name
CounterType      : NumberOfItems64
InstanceLifetime : Global
InstanceName     :
ReadOnly         : False
MachineName      : .
RawValue         : 20
Site             :
Container        :



PS C:\Users\doron> $counter.ReadOnly = 1
PS C:\Users\doron> $counter


CategoryName     : My category
CounterHelp      : My counter name
CounterName      : My counter name
CounterType      : NumberOfItems64
InstanceLifetime : Global
InstanceName     :
ReadOnly         : True
MachineName      : .
RawValue         : 0
Site             :
Container        :

服务器是 Windows 2008 R2,运行 .NET 4.5。

一个重要的注意事项是,我所有的其他性能计数器都不是这样,只有一些最近添加的性能计数器(这些是不起作用的)。对于所有其他计数器,无论是否为 ReadOnly,RawValue id 始终相同。

知道是什么原因造成的吗?

4

1 回答 1

5

由于您没有提供有关如何创建性能计数器以及谁在何时更新计数器的大量信息,因此我只能做出明智的猜测并告诉您两者之间的区别。

RawValue时间ReadOnly=True与时间的差异Readonly=False

根据 MSDN:

如果您正在读取的计数器是只读的,则获取 RawValue 属性会在调用该属性时对计数器进行采样。此操作相当于对 NextSample 方法进行初始调用。

来源:http: //msdn.microsoft.com/de-de/library/system.diagnostics.performancecounter.rawvalue.aspx

事实上,您可以通过查看 RawValue 属性的实际框架源来确认这一点:

public long RawValue
{
  get
  {
    if (this.ReadOnly)
      return this.NextSample().RawValue;
    this.Initialize();
    return this.sharedCounter.Value;
  }
  ...
}

MSDN 没有说明ReadOnly设置为时会发生什么False,但是查看上面的代码片段您会看到它会调用Initialize然后返回一个内部sharedCounter对象的值,该对象由Initialize. Initialize虽然在不同的地方被调用,但只有第一次调用会真正初始化对象。

因为代码比较复杂,所以没看懂完整的过程,但是好像性能计数器不是只读的时候会缓存这个值,所以你会看到一个旧值。

可能的解释

我必须在这里猜测,因为你没有说你实际上是如何进行测试的,但是如果你在更新任何值之前初始化性能计数器,那么我会假设你每次看到 RawValue 为 0,即使计数器被更新同时。

现在,只要将 ReadOnly 设置为 True 并再次查询 RawValue,您就会看到 PerformanceCounter 此时的实际值。

一个有趣的实验是调用NextSample()而不是使用RawValue. 在我看来,你应该在这两种情况下得到相同的结果。

希望这可以帮助!

于 2013-02-03T00:37:44.867 回答