这是我的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.
知道是什么原因引起的吗?
由于您没有提供有关如何创建性能计数器以及在何时更新计数器的大量信息,因此我只能做出明智的猜测并告诉您两者之间的区别.当ReadOnly = True与Readonly = False时RawValue的差异
根据MSDN:
If the counter that you are reading is read-only, getting the RawValue property samples the counter at the time that the property is called.This action is equivalent to making an initial call to the NextSample method.
资料来源: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然后返回由Initialize创建的内部sharedCounter对象的值.虽然初始化在各个地方被调用,但只有第一次调用才会真正初始化对象.
因为代码非常复杂,所以我不理解完整的过程,但似乎当性能计数器不是只读时会缓存该值,因此您将看到旧的值.
可能的解释
我必须在这里猜测,因为你没有说你实际上是如何进行测试的,但如果你在更新任何值之前初始化性能计数器,那么我会假设你每次都看到RawValue为0,即使计数器已更新同时.
现在,只要将ReadOnly设置为True并再次查询RawValue,就会看到PerformanceCounter此时具有的实际值.
一个有趣的实验是调用NextSample()而不是使用RawValue.在我看来,你应该在两种情况下得到相同的结果.
希望这可以帮助!