我在自定义性能计数器方面遇到一个奇怪的问题,我正在从Azure辅助角色创建和更新,以跟踪我的SOAP WCF服务的打开连接数。
在RoleEntryPoint.Run()
方法中,我确保创建了计数器:
if (PerformanceCounterCategory.Exists("WorkerRoleEndpointConnections"))
return true;
var soapCounter = new CounterCreationData
{
CounterName = "# SOAP Connections",
CounterHelp = "Current number of open SOAP connections",
CounterType = PerformanceCounterType.NumberOfItems32
};
counters.Add(soapCounter);
PerformanceCounterCategory.Create("WorkerRoleEndpointConnections", "Connection statistics for endpoint types", PerformanceCounterCategoryType.MultiInstance, counters);
这似乎可以正常工作,因为在角色启动时正确创建了计数器。我通过RDP检查了>性能监视器。
在检查/创建计数器之后,我立即使用PerformanceCounter
对象创建对计数器的单个引用:
m_SoapConnectionCounter = new PerformanceCounter
{
CategoryName = "WorkerRoleEndpointConnections",
CounterName = "# SOAP Connections",
MachineName = ".",
InstanceName = RoleEnvironment.CurrentRoleInstance.Id,
ReadOnly = false,
RawValue = 0L // Initialisation value added in an attempt to fix issue
};
然后我在需要时使用:
进行更新public async Task UpdateSoapConnectionCounter(int connections)
{
await UpdateCounter(m_SoapConnectionCounter, connections);
}
private async Task UpdateCounter(PerformanceCounter counter, int connections)
{
await Task.Run(() =>
{
counter.RawValue = connections; // Implicit cast to long
});
}
我的想法是,我只是在需要时以“一劳永逸”的方式覆盖该值。
问题是,这似乎只是偶尔 。随机地,计数器将显示一些大的值,其仅略大于int.MaxValue
,例如, 21474836353
。奇怪的是,一旦发生这种情况,它永远不会回到正常的#34;价值。
我尝试删除计数器,但即使在新创建它们时,它们似乎也会采用此值(有时从一开始),即使在创建PerformanceCounter
对象时添加初始化值为零。 / p>
我对这个问题可能会有点不知所措。起初我认为最初创建计数器时只是一个问题,但我现在也观察到计数器变为这些值 - 即0,1,2,1,21474836350
我只找到one post which indicates a similar issue,但唯一的建议是确保它已初始化,因为他们将问题归结为"未初始化的内存块,用于存储性能计数器变量&#34 ; - 但我尝试过这样做没有成功。
请注意,我不认为这是一个perfmon问题,因为我通过perfmon看到了这个问题,而且我还使用Azure诊断程序导出了计数器并且都显示了值。
任何想法?
答案 0 :(得分:1)
好的,经过多次调试后发现问题是因为有时候我给计数器分配了一个负数。
似乎将RawValue
属性设置为负数会导致某种位掩码,因此它实际上会赋予相当于int.MaxValue的值 - (负值)。