我试图找出为什么某些性能计数器没有在我们的生产服务器中更新,当我遇到这个奇怪的问题时 - 当计数器不是只读时,它似乎会返回不同的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。
知道可能导致这种情况的原因吗?
答案 0 :(得分: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
。在我看来,你应该在两种情况下得到相同的结果。
希望这有帮助!