Click here to Skip to main content
15,895,746 members
Articles / Programming Languages / C# 4.0

A Performance Counters Helper Class

Rate me:
Please Sign up or sign in to vote.
4.86/5 (9 votes)
16 Jan 2012CPOL3 min read 35.8K   726   36  
A performance counters helper class that makes it easier to use performance counters in your system, especially for measuring duration and total duration
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Core
{
    /// <summary>
    /// A base class for performance counters.
    /// </summary>
    public class PerformanceCountersManagerBase : IPerformanceCountersManager
    {
        private bool m_disposed;
        private Dictionary<string, PerformanceCounter> m_performanceCounters = 
            new Dictionary<string, PerformanceCounter>();
        private Dictionary<string, Stopwatch> m_stopwatches = new Dictionary<string, Stopwatch>();
        private Dictionary<string, long> m_counterValues = new Dictionary<string, long>();

        protected Dictionary<string, PerformanceCounter> PerformanceCounters
        {
            get
            {
                return m_performanceCounters;
            }
        }

        /// <summary>
        /// Starts the stopwatch for the given counter.
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        public void StartWatch(string counterName)
        {
            if (!m_stopwatches.ContainsKey(counterName))
            {
                m_stopwatches[counterName] = new Stopwatch();
            }

            m_stopwatches[counterName].Reset();
            m_stopwatches[counterName].Start();
        }

        /// <summary>
        /// Stops the stopwatch for the given counter.
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        public void StopWatch(string counterName)
        {
            if (!m_stopwatches.ContainsKey(counterName))
            {
                return;
            }
            m_stopwatches[counterName].Stop();
            UpdateCounter(counterName, m_stopwatches[counterName].ElapsedMilliseconds);
        }

        /// <summary>
        /// Updates the performance counter by the given value, if the counter exists.
        /// If the counter does not exist - return
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        /// <param name="value">The value.</param>
        public void UpdateCounter(string counterName, long value)
        {
            if (!m_performanceCounters.ContainsKey(counterName)) return;

            m_performanceCounters[counterName].RawValue = value;
        }

        /// <summary>
        /// Increments the specified counter value by 1, if the counter exists.
        /// If the counter does not exist - return
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        public void Increment(string counterName)
        {
            if (!m_performanceCounters.ContainsKey(counterName)) return;

            m_performanceCounters[counterName].Increment();
        }

        /// <summary>
        /// Increments the specified counter value by the given value, if the counter exists.
        /// If the counter does not exist - return
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        /// <param name="value">The value.</param>
        public void IncrementBy(string counterName, long value)
        {
            if (!m_performanceCounters.ContainsKey(counterName)) return;

            m_performanceCounters[counterName].IncrementBy(value);
        }

        /// <summary>
        /// Gets the elapsed milliseconds of the given counter.
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        /// <returns>If stopwatch exists for the counter returns elapsed milliseconds of the counter, 0 otherwise</returns>
        public long GetElapsedMilliseconds(string counterName)
        {
            return !m_stopwatches.ContainsKey(counterName) ? 0 : m_stopwatches[counterName].ElapsedMilliseconds;
        }

        /// <summary>
        /// Resets the counter value to zero.
        /// This does not change the actual performance counter, only its internal representation.
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        public void ResetCounterValue(string counterName)
        {
            m_counterValues[counterName] = 0;
        }

        /// <summary>
        /// Increment the counter value by the given value.
        /// This does not change the actual performance counter, only its internal representation.
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        /// <param name="value">The value.</param>
        public void IncrementCounterValueBy(string counterName, long value)
        {
            if (!m_counterValues.ContainsKey(counterName))
            {
                return;
            }
            m_counterValues[counterName] += value;
        }

        /// <summary>
        /// Change the value of the counter according to its internal value.
        /// You should use this after calling <see cref="IncrementCounterValueBy"/> when you want to actually
        /// change the counter value.
        /// </summary>
        /// <param name="counterName">Name of the counter.</param>
        public void UpdateCounter(string counterName)
        {
            if (!m_counterValues.ContainsKey(counterName)) return;

            UpdateCounter(counterName, m_counterValues[counterName]);
        }

        protected static PerformanceCounter CreateWritablePerformanceCounter(
            string category, string counterName, string instance)
        {
            return new PerformanceCounter(category, counterName, instance, false) { RawValue = 0 };
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                if (disposing)
                {
                    foreach (PerformanceCounter counter in m_performanceCounters.Values)
                    {
                        counter.RemoveInstance();
                        counter.Close();
                        counter.Dispose();
                    }
                }

                m_disposed = true;
            }
        }

        ~PerformanceCountersManagerBase()
        {
            Dispose(false);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Israel Israel
Ron is focused on .net and C# development since 2003.
In his various roles Ron was part of the whole release cycle starting from the initial requirements to release. Ron participated in Agile projects using Scrum and in projects managed with the waterfall methodology.
Ron worked as a developer, developer lead and as a test owner in a variety of technologies - languages like C# & Java, databases like MSSQL and more.
Ron always seeks for new opportunities to learn something new - whether a better development methodology, a design pattern or architecture to build better software.
Ron enjoys mentoring others on effective application development using SOLID design and architecture principles, test driven development and unit testing.

Comments and Discussions