Search code examples
c#performancecounter

Counter of type RateOfCountsPerSecond32 always shows 0


I have a windows service that serves messages of some virtual queue via a WCF service interface. I wanted to expose two performance counters -

  1. The number of items on the queue
  2. The number of items removed from the queue per second

The first one works fine, the second one always shows as 0 in PerfMon.exe, despite the RawValue appearing to be correct.

I'm creating the counters as such -

    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);
}

Then, on each service call, I increment the relevant counter, for the per/sec counter this currently looks like this -

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();

As mentioned - if I put a breakpoint after the call to increment I can see the RawValue constantly increasing, in consistence with the calls to the service (fairly frequently, more than once a second, I would think) But the performance counter itself stays on 0.

The performance counter providing the count of items on the 'queue', which is implemented in the same way (although I assign the RawValue, rather than call Increment) works just fine.

What am I missing?


Solution

  • I also initially had problems with this counter. MSDN has a full working example that helped me a lot:

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

    As their example was fairly long winded, I boiled it down to a single method to demonstrate the bare essentials. When run, I see the expected value of 10 counts per second in PerfMon.

    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);
        }
    }
    

    I hope this helps someone.