Some time ago I added performance counters to the application I was working on, and for some inexplicable reason all counters of "Average" type, like AverageCount64 or AverageTimer32, didn't work at all, always having 0 value. Then I had no time to find out why it was not working, but today I did. As you may know, "Average" counters are made of two distinct counters: the base counter and the average counter itself. The mystery was that by looking at all the samples returned by Google, it was unclear how the Base and the Average itself are linked together. It looked like you create the Base and the Average, add them to the collection and somehow magically Windows figures they need to be linked together when averages are calculated. After some research it looks like the two are linked by counter name! It appears that base's name should be the name of real counter, plus word " base". For example, when you define your counter category that has average performance counter, you do something like this:
counters.Add(new CounterCreationData("whatever", "whatever desc", PerformanceCounterType.AverageCount64));
counters.Add(new CounterCreationData("whatever base", "whatever base desc", PerformanceCounterType.AverageBase));
To my surprise, changing the "whatever base" value of the counter name in both CounterCreationData and PerformanceCounter to something like "whatever base1" breaks the perf counter! It looks like there is a naming convention requiring that AverageBase proformance counter has the CounterName property value on both CounterCreationData and PerformanceCounter to be counter name plus " base", but I never saw this mentioned anywhere - neither by MSDN, nor by Codeproject articles. So, since average perf counters always come in pairs, linked by name, these helpers should make creating average perf counters simpler (uinsg C#/.NET):
private static void AddAverageCounterDefinition(CounterCreationDataCollection counters,
string counterName, string counterDescription, PerformanceCounterType averageType)
{
counters.Add(new CounterCreationData(counterName, counterDescription, averageType));
counters.Add(new CounterCreationData(counterName + " base", string.Empty, PerformanceCounterType.AverageBase));
}
public class AveragePerfCounter
{
private PerformanceCounter averageCounter;
private PerformanceCounter averageCounterBase;
public AveragePerfCounter(string categoryName, string counterName)
{
this.averageCounter = new PerformanceCounter(categoryName, counterName, false);
this.averageCounterBase = new PerformanceCounter(categoryName, counterName + " base", false);
}
public void IncrementBy(long val)
{
this.averageCounter.IncrementBy(val);
this.averageCounterBase.Increment();
}
}
After this, when creating performance counter definition, you could use following code instead of the one shown by the very first snippet:
AddAverageCounterDefinition(counters, "whatever", "whatever desc", PerformanceCounterType.AverageCount64);
It will add " base" to the name of the sidekick automatically.
And to create corresponding performance counter, you now can do this:
AveragePerfCounter avgCount = new AveragePerfCounter("MyCategory", "whatever");
avgCount.IncrementBy(new Random().Next(100));