当ReadOnly = false时,性能计数器显示不同的值

时间:2013-01-23 12:17:23

标签: .net windows powershell performancecounter

我试图找出为什么某些性能计数器没有在我们的生产服务器中更新,当我遇到这个奇怪的问题时 - 当计数器不是只读时,它似乎会返回不同的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。

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

知道可能导致这种情况的原因吗?

1 个答案:

答案 0 :(得分:5)

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

RawValueReadOnly=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。在我看来,你应该在两种情况下得到相同的结果。

希望这有帮助!