RateOfCountsPerSecond32类型的计数器始终显示0

我有一个Windows服务,通过WCF服务接口提供某些虚拟队列的消息。 我想揭露两个性能指标 –

  1. 队列中的项目数
  2. 每秒从队列中删除的项目数

第一个工作正常,第二个在PerfMon.exe中始终显示为0,尽管RawValue看起来是正确的。

我正在创建计数器 –

internal const string PERF_COUNTERS_CATEGORY = "HRG.Test.GDSSimulator"; internal const string PERF_COUNTER_ITEMSINQUEUE_COUNTER = "# Messages on queue"; internal const string PERF_COUNTER_PNR_PER_SECOND_COUNTER = "# Messages read / sec"; if (!PerformanceCounterCategory.Exists(PERF_COUNTERS_CATEGORY)) { System.Diagnostics.Trace.WriteLine("Creating performance counter category: " + PERF_COUNTERS_CATEGORY); CounterCreationDataCollection counters = new CounterCreationDataCollection(); CounterCreationData numberOfMessagesCounter = new CounterCreationData(); numberOfMessagesCounter.CounterHelp = "This counter provides the number of messages exist in each simulated queue"; numberOfMessagesCounter.CounterName = PERF_COUNTER_ITEMSINQUEUE_COUNTER; numberOfMessagesCounter.CounterType = PerformanceCounterType.NumberOfItems32; counters.Add(numberOfMessagesCounter); CounterCreationData messagesPerSecondCounter= new CounterCreationData(); messagesPerSecondCounter.CounterHelp = "This counter provides the number of messages read from the queue per second"; messagesPerSecondCounter.CounterName = PERF_COUNTER_PNR_PER_SECOND_COUNTER; messagesPerSecondCounter.CounterType = PerformanceCounterType.RateOfCountsPerSecond32; counters.Add(messagesPerSecondCounter); PerformanceCounterCategory.Create(PERF_COUNTERS_CATEGORY, "HRG Queue Simulator performance counters", PerformanceCounterCategoryType.MultiInstance,counters); } 

然后,在每次服务呼叫时,我增加相关的计数器,对于每秒/秒计数器,这当前看起来像这样 –

 messagesPerSecCounter = new PerformanceCounter(); messagesPerSecCounter.CategoryName = QueueSimulator.PERF_COUNTERS_CATEGORY; messagesPerSecCounter.CounterName = QueueSimulator.PERF_COUNTER_PNR_PER_SECOND_COUNTER; messagesPerSecCounter.MachineName = "."; messagesPerSecCounter.InstanceName = this.ToString().ToLower(); messagesPerSecCounter.ReadOnly = false; messagesPerSecCounter.Increment(); 

如上所述 – 如果我在增加调用之后放置一个断点,我可以看到RawValue不断增加,与服务调用一致(相当频繁,每秒不止一次,我想)但是性能计数器本身保持不变0。

提供“队列”项目计数的性能计数器,以相同的方式实现(虽然我分​​配RawValue,而不是调用Increment)工作得很好。

我错过了什么?

我最初也有这个柜台的问题。 MSDN有一个完整的工作示例,帮助了我很多:

http://msdn.microsoft.com/en-us/library/4bcx21aa.aspx

由于他们的例子相当长,我把它归结为一种方法来展示最基本的东西。 运行时,我在PerfMon中看到每秒10个计数的预期值。

 public static void Test() { var ccdc = new CounterCreationDataCollection(); // add the counter const string counterName = "RateOfCountsPerSecond64Sample"; var rateOfCounts64 = new CounterCreationData { CounterType = PerformanceCounterType.RateOfCountsPerSecond64, CounterName = counterName }; ccdc.Add(rateOfCounts64); // ensure category exists const string categoryName = "RateOfCountsPerSecond64SampleCategory"; if (PerformanceCounterCategory.Exists(categoryName)) { PerformanceCounterCategory.Delete(categoryName); } PerformanceCounterCategory.Create(categoryName, "", PerformanceCounterCategoryType.SingleInstance, ccdc); // create the counter var pc = new PerformanceCounter(categoryName, counterName, false); // send some sample data - roughly ten counts per second while (true) { pc.IncrementBy(10); System.Threading.Thread.Sleep(1000); } } 

我希望这可以帮助别人。

当您使用Average类型性能计数器时,有两个组件 – 分子和分母。 因为您正在使用平均值,所以计数器计算为“每y个实例的x个实例”。 在你的情况下,你每个’秒数’计算’数字项’。 换句话说,您需要计算从队列中取出的项目数以及要删除它们所需的秒数。

Average类型性能计数器实际上创建了两个计数器 – 一个名为{name}的分子组件和一个名为{name}Base的分母组件。 如果转到“性能计数器”管理单元,则可以查看所有类别和计数器; 你可以检查Base计数器的名称。 当队列处理过程开始时,你应该

  • 开始秒表
  • 从队列中删除项目
  • 停止秒表
  • {name}计数器增加从队列中删除的项目数
  • {name}Base计数器增加秒表上的刻度数

计数器应该自动知道将第一个计数器除以第二个计数器以给出平均速率。 检查CodeProject以获取其工作原理的一个很好的示例。


你很可能不想要这种类型的计数器。 这些Average计数器用于确定每秒操作发生的实例数; 例如,完成订单或执行某些复杂交易或流程所需的平均秒数。 您可能需要的是“实际”时间的平均实例数,而不是处理时间。

考虑一下你的队列中是否有1个项目,需要1ms才能删除,这是每秒1000个项目的速度。 但是在一秒之后你只删除了一个项目(因为那就是全部),所以你在’实际’时间内每秒处理1个项目。 同样,如果队列中有一百万个项目,但由于您的服务器忙于完成其他工作,您只处理了一个项目,您是否希望看到1000项/秒理论值或1项/秒真实值?

如果您想要这个“真实”数字,而不是理论吞吐量数字,那么这种情况并不适合性能计数器 – 而是需要知道开始时间和结束时间以及处理的许多项目。 用一个简单的“计数器”无法做到这一点。 相反,您会在某处存储系统启动时间,并计算(number of items) / (now - startup time)

我有同样的问题。 在我的测试中,我相信我看到的问题是多实例和每秒计数率的某种组合。 如果我使用单个实例或许多项目反击它工作。 关于多实例和每秒速率的组合使得它总是为零。

由于RateOfCountsPerSecond64类型的性能计数器始终为值0 ,因此重新启动可能会起作用 。 无论如何,为我工作。

另一件对我有用的事情就是在这样的块中初始化计数器:

 counter.BeginInit(); counter.RawValue = 0; counter.EndInit(); 

我认为你需要一些方法来坚持反击。 在我看来,每次启动服务调用时,都会重新创建计数器。

因此,如果您希望计数器对用户来说是唯一的,那么您可以将计数器保存到数据库,平面文件或甚至是会话变量。