当 ReadOnly=false 时,性能计数器显示不同的值
Posted
技术标签:
【中文标题】当 ReadOnly=false 时,性能计数器显示不同的值【英文标题】:Performance Counter shows different values when ReadOnly=false 【发布时间】:2013-01-23 12:17:23 【问题描述】:当我遇到这个奇怪的问题时,我试图弄清楚为什么某些性能计数器没有在我们的生产服务器中更新 - 当计数器不是只读时,它似乎返回不同的 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 始终相同。
知道是什么原因造成的吗?
【问题讨论】:
您能否提供更多信息,首先您是如何获得 $counter 价值的。 我一开始就加了 @DoronYaacoby,你找到解决这个问题的方法了吗?我有完全同样的问题,并且非常感谢任何可能导致解决方案的信息。请... @DoronYaacoby,很抱歉再次询问,但如果您解决了这个问题,解决方案是什么?如果您不想回复 SO,请通过 gmail dot com 的 dnovatchev 与我联系 @DimitreNovaatchev 抱歉,但不,我从来没有解决它。我们最终放弃了自定义性能计数器。 【参考方案1】:由于您没有提供很多关于如何创建性能计数器以及谁在什么时候更新计数器的信息,我只能做出明智的猜测并告诉您两者之间的区别。
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
时会发生什么,但是查看上面的代码 sn-p 你会发现它会调用 Initialize
然后返回内部 sharedCounter
的值对象,由Initialize
创建。 Initialize
在不同的地方被调用,只有第一次调用才会真正初始化对象。
因为代码比较复杂,所以没看懂完整的过程,但是好像性能计数器不是只读的时候会缓存这个值,所以你会看到一个旧的值。
可能的解释
我必须在这里猜测,因为你没有说你实际上是如何进行测试的,但是如果你在更新任何值之前初始化性能计数器,那么我会假设你每次看到 RawValue 为 0,即使计数器同时更新。
现在只要将 ReadOnly 设置为 True 并再次查询 RawValue,您就会看到 PerformanceCounter 此时的实际值。
一个有趣的实验是调用NextSample()
而不是使用RawValue
。我认为你应该在这两种情况下得到相同的结果。
希望这会有所帮助!
【讨论】:
当我尝试通过 PowerShell 读取它的值时,计数器已经初始化并写入。此外,我的大多数计数器都可以工作,只有几个新添加的计数器表现异常。 您能提供更多信息吗?你如何创建计数器对象?你如何编写/更新计数器?问题是对于 RawValue,只读和非只读之间的区别是什么。我查看了实际代码并想出了这个。这是唯一的区别。如果这不是问题,那么您可能找错地方了。尝试在一个小型示例项目中重现该问题。你也试过 NextSample 吗? ReadOnly=True 时计数器是否按预期工作。 性能计数器的创建方式没有什么有趣的。这是完全标准的 - 我创建了一个 CounterCreationData 对象,该对象被添加到 PerformanceCounterCollection,然后用于调用 PerformanceCounterCategory.Create。 $counter.NextSample() 无论计数器是否为只读,都会产生 0。不,计数器没有按预期工作,无论我增加多少,它都会保持在 0 上。这不会在示例项目中重现,此特定计数器有问题,我试图了解是什么。 很抱歉,我不能提供更多帮助 :-( 与其做一个示例项目,也许您可以越来越多地减少实际项目,直到您拥有仍然发生错误的最低版本。除此之外,没有太多真正区分计数器...如果在示例项目中使用相同的计数器不会重现问题,那么我认为问题不在于计数器,而在于应用程序。你设置了吗断点,添加日志记录以确保性能计数器确实被写入?这可以在另一台计算机上重现吗?以上是关于当 ReadOnly=false 时,性能计数器显示不同的值的主要内容,如果未能解决你的问题,请参考以下文章
当 JDBC AutoCommit 为 False 且未设置显式事务边界时会发生啥