Click here to Skip to main content
15,896,453 members
Articles / Programming Languages / C#

Using Custom Attributes to Create Performance Counters

Rate me:
Please Sign up or sign in to vote.
3.58/5 (9 votes)
12 Jun 2007CPOL3 min read 62K   762   35  
This article describes how to use custom attributes to automate performance counter and category creation.
using System;
using System.Diagnostics;
using System.Reflection;

namespace Common.Diagnostics
{
	/// <summary>
	/// Attribute to tag the performance counters for a given class to a performance counter category.
	/// </summary>
	/// <remarks>
	/// Attribute to tag the performance counters for a given class to a performance counter category.
	/// </remarks>
	[AttributeUsage(AttributeTargets.Class)]
	public class PerformanceCounterCategoryAttribute : Attribute
	{
		private string name;
		private string help;
        private PerformanceCounterCategoryType categoryType;

		/// <summary>
		/// Constructor
		/// </summary>
		/// <remarks>
		/// PerformanceCounterCategoryType defaults to Unknown
		/// </remarks>
		/// <param name="name">Performance counter category name.</param>
		public PerformanceCounterCategoryAttribute(string name) : this(name, null, PerformanceCounterCategoryType.Unknown)
		{
			// nothing to do
		}

		/// <summary>
		/// Constructor
		/// </summary>
		/// <remarks>
        /// PerformanceCounterCategoryType defaults to Unknown
        /// </remarks>
		/// <param name="name">Performance counter category name.</param>
		/// <param name="help">Performance counter category help.</param>
		public PerformanceCounterCategoryAttribute(string name, string help) : this(name, help, PerformanceCounterCategoryType.Unknown)
		{
            // nothing to do
        }
        
        /// <summary>
        /// Constructor
        /// </summary>
        /// <remarks>
        /// Constructor
        /// </remarks>
        /// <param name="name">Performance counter category name.</param>
        /// <param name="categoryType">Performance counter category type.</param>
        public PerformanceCounterCategoryAttribute(string name, PerformanceCounterCategoryType categoryType) : this(name, null, categoryType)
        {
            // nothing to do
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <remarks>
        /// Constructor
        /// </remarks>
        /// <param name="name">Performance counter category name.</param>
        /// <param name="help">Performance counter category help.</param>
        /// <param name="categoryType">Performance counter category type.</param>
        public PerformanceCounterCategoryAttribute(string name, string help, PerformanceCounterCategoryType categoryType)
        {
            this.name = name;
            this.help = help;
            this.categoryType = categoryType;
        }
        
		/// <summary>
		/// Gets the performance counter category.
		/// </summary>
		/// <remarks>
		/// Gets the performance counter category.
		/// </remarks>
		public string Name
		{
			get { return name; }
		}

		/// <summary>
		/// Gets the performance counter category help.
		/// </summary>
		/// <remarks>
		/// Gets the performance counter category help.
		/// </remarks>
		public string Help
		{
			get { return help; }
		}

        /// <summary>
        /// Gets the performance counter category type.
        /// </summary>
        /// <remarks>
        /// Default is Unknown.
        /// </remarks>
        public PerformanceCounterCategoryType CategoryType
        {
            get { return categoryType; }
        }
	}

	/// <summary>
	/// Defines a performance counter for the class that it is tagged with it.
	/// </summary>
	[AttributeUsage(AttributeTargets.Field)]
	public class PerformanceCounterAttribute : Attribute
	{
		#region Private Members

		string name;
		string help;
		string instance;
		PerformanceCounterType type;

		#endregion

		#region Constructor

		/// <summary>
		/// Creates a new performance counter attribute with the given counter name.
		/// </summary>
		/// <remarks>
		/// Creates a new performance counter attribute with the given counter name.
		/// </remarks>
		/// <param name="name">Counter name.</param>
		public PerformanceCounterAttribute(string name) : this(name, null, PerformanceCounterType.NumberOfItems64, null)
		{
			// nothing to do
		}

		/// <summary>
		/// Creates a new performance counter attribute with the given counter name and type.
		/// </summary>
		/// <remarks>
		/// Creates a new performance counter attribute with the given counter name and type.
		/// </remarks>
		/// <param name="name">Counter name.</param>
		/// <param name="type">Counter type.</param>
		public PerformanceCounterAttribute(string name, PerformanceCounterType type) : this(name, null, type, null)
		{
			// nothing to do
		}

		/// <summary>
		/// Creates a new performance counter attribute with the given counter name and type.
		/// </summary>
		/// <remarks>
		/// Creates a new performance counter attribute with the given counter name and type.
		/// </remarks>
		/// <param name="name">Counter name.</param>
		/// <param name="type">Counter type.</param>
		/// <param name="instance">Counter instance name.</param>
		public PerformanceCounterAttribute(string name, PerformanceCounterType type, string instance) : this(name, null, type, instance)
		{
			// nothing to do
		}

		/// <summary>
		/// Creates a new performance counter attribute with the given counter name and type.
		/// </summary>
		/// <remarks>
		/// Creates a new performance counter attribute with the given counter name and type.
		/// </remarks>
		/// <param name="name">Counter name.</param>
		/// <param name="help">Counter help.</param>
		/// <param name="type">Counter type.</param>
		public PerformanceCounterAttribute(string name, string help, PerformanceCounterType type) : this(name, help, type, null)
		{
			// nothing to do
		}

		/// <summary>
		/// Creates a new performance counter attribute with the given counter name, help, member name and type.
		/// </summary>
		/// <remarks>
		/// Creates a new performance counter attribute with the given counter name, help, member name and type.
		/// </remarks>
		/// <param name="name">Counter name.</param>
		/// <param name="type">Counter type.</param>
		/// <param name="help">Counter help.</param>
		/// <param name="instance">Counter instance name.</param>
		public PerformanceCounterAttribute(string name, string help, PerformanceCounterType type, string instance)
		{
			this.name = name;
			this.instance = (instance == null) ? string.Empty : instance;
			this.help = help;
			this.type = type;
		}

		#endregion

		#region Properties

		/// <summary>
		/// Gets the performance counter name.
		/// </summary>
		/// <remarks>
		/// Gets the performance counter name.
		/// </remarks>
		public string Name { get { return name; }}
 
		/// <summary>
		/// Gets the performance counter instance name.
		/// </summary>
		/// <remarks>
		/// Gets the performance counter instance name.
		/// </remarks>
		public string Instance { get { return instance; }}

		/// <summary>
		/// Gets the performance counter help.
		/// </summary>
		/// <remarks>
		/// Gets the performance counter help.
		/// </remarks>
		public string Help { get { return help; }}

		/// <summary>
		/// Gets the type of the performance counter.
		/// </summary>
		/// <remarks>
		/// Gets the type of the performance counter.
		/// </remarks>
		public PerformanceCounterType Type { get { return type; }}

		#endregion
	}

	/// <summary>
	/// Wrapper and Helper class for a category of performance counters.
	/// </summary>
	/// <remarks>
	/// Wrapper and Helper class for a category of performance counters.
	/// </remarks>
	public class PerformanceCounterFactory
	{
		#region Private Members

		private string categoryName;
		private string categoryHelp;
        private PerformanceCounterCategoryType categoryType;
		private CounterCreationDataCollection counters;

		#endregion

		#region Constructor

		/// <summary>
		/// Creates a new performance counter category with the given name and help description.
		/// </summary>
		/// <remarks>
		/// Creates a new performance counter category with the given name and help description.
		/// </remarks>
		/// <param name="categoryName">Performance counter category name.</param>
		/// <param name="categoryHelp">Performance counter category help text.</param>
		public PerformanceCounterFactory(string categoryName, string categoryHelp)
		{
			this.categoryName = categoryName;
			this.categoryHelp = categoryHelp;
            this.categoryType = PerformanceCounterCategoryType.Unknown;
			counters = new CounterCreationDataCollection();
		}

		/// <summary>
		/// Creates a new performance counter category with the given name.
		/// </summary>
		/// <remarks>
		/// Creates a new performance counter category with the given name.
		/// </remarks>
		/// <param name="categoryName"></param>
		public PerformanceCounterFactory(string categoryName) : this(categoryName, null)
		{
			// nothing to do
		}

		/// <summary>
		/// Creates a new category for the specified type.
		/// </summary>
		/// <remarks>
		/// Type must have <c>PerformanceCounterCategoryAttribute</c> and <c>PerformanceCounterAttributes</c> set.
		/// </remarks>
		/// <exception cref="ArgumentException">
		/// Thrown if the specified type has no performance counter category attribute set.
		/// </exception>
		/// <param name="type">Type to create Performance counters for.</param>
		public PerformanceCounterFactory(Type type)
		{
			counters = new CounterCreationDataCollection();

			PerformanceCounterCategoryAttribute category = GetCategory(type);
			if (category == null) throw new ArgumentException(String.Format("Type {0} has no PerformanceCounterCategory attribute", type.Name), "type");

			this.categoryName = category.Name;
			this.categoryHelp = category.Help;
            this.categoryType = category.CategoryType;

			_AddCounters(type);
		}		

		#endregion

		#region Properties

		/// <summary>
		/// Gets the performance counter category name.
		/// </summary>
		/// <value>
		/// Performance counter category name.
		/// </value>
		public string Name
		{
			get { return categoryName; }
		}

		/// <summary>
		/// Gets the performance counter category help.
		/// </summary>
		/// <value>
		/// Performance counter category help.
		/// </value>
		public string Help
		{
			get { return categoryHelp; }
		}

        /// <summary>
        /// Gets the performance counter category Type.
        /// </summary>
        /// <value>
        /// Performance counter category type.
        /// </value>
        public PerformanceCounterCategoryType CategoryType
        {
            get { return categoryType; }
        }

		/// <summary>
		/// Gets a writable instance of a performance counter in this category.
		/// </summary>
		/// <value>
		/// Writable instance of a performance counter in this category.
		/// </value>
		public PerformanceCounter this[string counterName]
		{
			get { return GetCounter(categoryName, counterName, false); }
		}

		/// <summary>
		/// Gets the counter creation data collection
		/// </summary>
		/// <remarks>
		/// Can be passed to a PerformanceCounterInstaller.
		/// </remarks>
		public CounterCreationDataCollection Counters
		{
			get { return counters; }
		}

		#endregion

		#region Public Methods

		/// <summary>
		/// Gets an instance of the specified performance counter in this category.
		/// </summary>
		/// <param name="counterName">Performance counter name.</param>
		/// <param name="instanceName">Performance counter instance name.</param>
		/// <param name="readOnly">If true, the returned counter is readonly. If false, the returned counter is writable.</param>
		/// <returns>Performance counter instance.</returns>
		public PerformanceCounter GetCounter(string counterName, string instanceName, bool readOnly)
		{
			return GetCounter(categoryName, counterName, instanceName, readOnly);
		}

		/// <summary>
		/// Gets a readonly instance of the specified performance counter in this category.
		/// </summary>
		/// <param name="counterName">Performance counter name.</param>
		/// <param name="instanceName">Performance counter instance name.</param>
		/// <returns>Performance counter instance.</returns>
		public PerformanceCounter GetCounter(string counterName, string instanceName)
		{
			return GetCounter(counterName, instanceName, false);
		}

		/// <summary>
		/// Gets an instance of the specified performance counter in this category.
		/// </summary>
		/// <param name="counterName">Performance counter name.</param>
		/// <param name="readOnly">If true, the returned counter is readonly. If false, the returned counter is writable.</param>
		/// <returns>Performance counter instance.</returns>
		public PerformanceCounter GetCounter(string counterName, bool readOnly)
		{
			return GetCounter(categoryName, counterName, string.Empty, readOnly);
		}

		/// <summary>
		/// Gets a readonly instance of the specified performance counter in this category.
		/// </summary>
		/// <param name="counterName">Performance counter name</param>
		/// <returns>Performance counter instance.</returns>
		public PerformanceCounter GetCounter(string counterName)
		{
			return GetCounter(counterName, false);
		}

		/// <summary>
		/// Adds a performance counter of the given type to the category collection.
		/// </summary>
		/// <remarks>
		/// Adds a performance counter of the given type to the category collection.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		/// <param name="type">Performance counter type.</param>
		/// <param name="help">Performance counter help text.</param>
		public void AddCounter(string name, PerformanceCounterType type, string help)
		{
			CounterCreationData counter = new CounterCreationData();
			counter.CounterName = name;
			counter.CounterType = type;
			if (help != null)
				counter.CounterHelp = help;

			counters.Add(counter);
		}

		/// <summary>
		/// Adds a performance counter of the given type to the category collection.
		/// </summary>
		/// <remarks>
		/// Adds a performance counter of the given type to the category collection.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		/// <param name="type">Performance counter type.</param>
		public void AddCounter(string name, PerformanceCounterType type)
		{
			AddCounter(name, type, null);
		}

		/// <summary>
		/// Adds a NumberOfItems64 performance counter to the category collection.
		/// </summary>
		/// <remarks>
		/// Adds a NumberOfItems64 performance counter to the category collection.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		/// <param name="help">Performance counter help text.</param>
		public void AddNumberCounter(string name, string help)
		{
			AddCounter(name, PerformanceCounterType.NumberOfItems64, help);
		}

		/// <summary>
		/// Adds a NumberOfItems64 performance counter to the category collection.
		/// </summary>
		/// <remarks>
		/// Adds a NumberOfItems64 performance counter to the category collection.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		public void AddNumberCounter(string name)
		{
			AddCounter(name, PerformanceCounterType.NumberOfItems64, null);
		}

		/// <summary>
		/// Adds a RateOfCountsPerSecond64 performance counter to the category collection.
		/// </summary>
		/// <remarks>
		/// Adds a RateOfCountsPerSecond64 performance counter to the category collection.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		/// <param name="help">Performance counter help text.</param>
		public void AddRateCounter(string name, string help)
		{
			AddCounter(name, PerformanceCounterType.RateOfCountsPerSecond64, help);
		}

		/// <summary>
		/// Adds a RateOfCountsPerSecond64 performance counter to the category collection.
		/// </summary>
		/// <remarks>
		/// Adds a RateOfCountsPerSecond64 performance counter to the category collection.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		public void AddRateCounter(string name)
		{
			AddCounter(name, PerformanceCounterType.RateOfCountsPerSecond64);
		}

		/// <summary>
		/// Adds a AverageCount64 performance counter to the category collection.
		/// </summary>
		/// <remarks>
		/// Also adds the required base counter.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		/// <param name="help">Performance counter help text.</param>
		public void AddAverageCounter(string name, string help)
		{
			// add average counter
			AddCounter(name, PerformanceCounterType.AverageCount64, help);
			// add the corresponding base counter
			AddCounter(name + "Base", PerformanceCounterType.AverageBase, null);
		}

		/// <summary>
		/// Adds a AverageCount64 performance counter to the category collection.
		/// </summary>
		/// <remarks>
		/// Also adds the required base counter.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		public void AddAverageCounter(string name)
		{
			AddAverageCounter(name, null);
		}

		/// <summary>
		/// Adds a RawFraction performance counter to the category collection.
		/// </summary>
		/// <remarks>
		/// Also adds the required base counter.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		/// <param name="help">Performance counter help text.</param>
		public void AddFractionCounter(string name, string help)
		{
			// add average counter
			AddCounter(name, PerformanceCounterType.RawFraction, help);
			// add the corresponding base counter
			AddCounter(name + "Base", PerformanceCounterType.RawBase, null);
		}

		/// <summary>
		/// Adds a RawFraction performance counter to the category collection.
		/// </summary>
		/// <remarks>
		/// Also adds the required base counter.
		/// </remarks>
		/// <param name="name">Performance counter name.</param>
		public void AddFractionCounter(string name)
		{
			AddFractionCounter(name, null);
		}


		/// <summary>
		/// Adds all performance counter for the specified Type to this category.
		/// </summary>
		/// <remarks>
		/// Performance category name of the Type must match the one of this category instance.
		/// </remarks>
		/// <param name="type">Type</param>
		public void AddCounters(Type type)
		{
			PerformanceCounterCategoryAttribute category = GetCategory(type);
			if (category == null) 
				throw new ArgumentException(String.Format("Type {0} has no PerformanceCounterCategory attribute", type.Name), "type");

			if (category.Name != this.categoryName)
				throw new ArgumentException("Category names do not match");

			_AddCounters(type);
		}

		/// <summary>
		/// Indicates if the performance counter category exists.
		/// </summary>
		/// <remarks>
		/// Indicates if the performance counter category exists.
		/// </remarks>
		/// <returns>True if it does exist, false otherwise.</returns>
		public bool Exists()
		{
			return Exists(categoryName);
		}

		/// <summary>
		/// Creates performance counter category and counters.
		/// </summary>
		/// <remarks>
		/// If the category already exists only non existing counters are added.
		/// </remarks>
		public void Create()
		{
			if (!Exists(categoryName))
			{
				// category does not exist, create
				PerformanceCounterCategory.Create(
                    categoryName, 
                    categoryHelp != null ? categoryHelp : "", 
                    categoryType, 
                    counters);
			}
		}

		/// <summary>
		/// Deletes the performance counter category and counters.
		/// </summary>
		/// <remarks>
		/// Deletes the performance counter category and counters.
		/// </remarks>
		public void Delete()
		{
			Delete(categoryName);
		}

		#endregion

		#region Private Methods

		/// <summary>
		/// Gets the performance counter category attribute attached to the type.
		/// </summary>
		/// <remarks>
		/// </remarks>
		/// <param name="type"></param>
		/// <returns>The performance counter category attribute on success, null otherwise</returns>
		private PerformanceCounterCategoryAttribute GetCategory(Type type)
		{
			// get category attribute
			object[] attributes = type.GetCustomAttributes(typeof(PerformanceCounterCategoryAttribute), false);

			// we don't have performance counter category, give up
			if (attributes.Length < 1) return null;
 
			return (PerformanceCounterCategoryAttribute)attributes[0];
		}

		/// <summary>
		/// Populates the CounterCreationDataCollection for a given type.
		/// </summary>
		/// <param name="type">Type to search for performance counters.</param>
		private void _AddCounters(Type type)
		{
			foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic))
			{
				// ignore member if it is not a performance counter
				if (field.FieldType != typeof(PerformanceCounter)) continue;

				// get the performance counter attribute
				object[] attributes = field.GetCustomAttributes(typeof(PerformanceCounterAttribute), false);
				// ignore it if it has no performance counter attribute set
				if (attributes.Length < 1) continue;

				// assign the performance counter
				PerformanceCounterAttribute counter = (PerformanceCounterAttribute)attributes[0];
				// only create a counter with multiple instances once 
				if (counter.Instance != string.Empty && Exists(counter))
					continue;
				
				AddCounter(counter.Name, counter.Type, counter.Help);

				// create base counter if needed
				switch (counter.Type)
				{
					case PerformanceCounterType.AverageCount64:
					case PerformanceCounterType.AverageTimer32:
						AddCounter(counter.Name + "Base", PerformanceCounterType.AverageBase);
						break;
					case PerformanceCounterType.RawFraction:
						AddCounter(counter.Name + "Base", PerformanceCounterType.RawBase);
						break;
					case PerformanceCounterType.CounterMultiTimer:
					case PerformanceCounterType.CounterMultiTimerInverse:
					case PerformanceCounterType.CounterMultiTimer100Ns:
					case PerformanceCounterType.CounterMultiTimer100NsInverse:
						AddCounter(counter.Name + "Base", PerformanceCounterType.CounterMultiBase);
						break;
					case PerformanceCounterType.SampleCounter:
					case PerformanceCounterType.SampleFraction:
						AddCounter(counter.Name + "Base", PerformanceCounterType.SampleBase);
						break;
					default: break;
				}
			}
		}

		/// <summary>
		/// Checks if a counter by the same name already exists in the counter creation data collection.
		/// </summary>
		/// <remarks>
		/// Counter names must be unique within a category.
		/// </remarks>
		/// <param name="counter">Performance counter attribute.</param>
		/// <returns><b>True</b> if the counter already exists, <b>false</b> otherwise.</returns>
		private bool Exists(PerformanceCounterAttribute counter)
		{
			foreach (CounterCreationData creationData in counters)
			{
				if (creationData.CounterName == counter.Name)
					return true;
			}

			return false;
		}

		#endregion

		#region Static Methods

		/// <summary>
		/// Gets a performance counter instance for a given name and category.
		/// </summary>
		/// <remarks>
		/// Gets a performance counter instance for a given name and category.
		/// </remarks>
		/// <param name="categoryName">Performance counter category.</param>
		/// <param name="counterName">Performance counter name.</param>
		/// <param name="instanceName">Performance counter instance name.</param>
		/// <param name="readOnly">ReadOnly</param>
		/// <returns>Performance counter instance.</returns>
		public static PerformanceCounter GetCounter(string categoryName, string counterName, string instanceName, bool readOnly)
		{
			return new PerformanceCounter(categoryName, counterName, instanceName, readOnly);
		}

		/// <summary>
		/// Checks if a performance counter category exists.
		/// </summary>
		/// <param name="categoryName">Performance counter category name.</param>
		/// <returns>True if the category exists, false otherwise.</returns>
		public static bool Exists(string categoryName)
		{
			return PerformanceCounterCategory.Exists(categoryName);
		}

		/// <summary>
		/// Deletes the specified performance counter category and counters.
		/// </summary>
		/// <remarks>
		/// Deletes the specified performance counter category and counters.
		/// </remarks>
		/// <param name="categoryName">Performance counter category name.</param>
		public static void Delete(string categoryName)
		{
			PerformanceCounterCategory.Delete(categoryName);
		}

		/// <summary>
		/// Creates instances for all performance counter members in the given type.
		/// </summary>
		/// <remarks>
		/// The type must have the PerformanceCounterCategory attribute set. Each performance counter
		/// member must be static and tagged with a PerformanceCounter attribute.
		/// </remarks>
		/// <param name="type">Type to instantiate counters</param>
		/// <returns><b>True</b> if counters were created successfully, <b>false</b> otherwise.</returns>
		public static bool CreateCounters(Type type)
		{
			return CreateCounters(type, null);	
		}
		
		/// <summary>
		/// Creates instances for all performance counter members in the given type.
		/// </summary>
		/// <remarks>
		/// The type must have the PerformanceCounterCategory attribute set. Each performance counter
		/// member must be static and tagged with a PerformanceCounter attribute.
		/// </remarks>
		/// <param name="type">Type to instantiate counters</param>
		/// <param name="instance">Instance to assign performance counters to.</param>
		/// <returns><b>True</b> if counters were created successfully, <b>false</b> otherwise.</returns>
		public static bool CreateCounters(Type type, object instance)
		{
			Debug.Assert(instance == null || type == instance.GetType() || instance.GetType().IsSubclassOf(type));

			// get category attribute
			object[] attributes = type.GetCustomAttributes(typeof(PerformanceCounterCategoryAttribute), false);

			// we don't have performance counter category, we are done
			if (attributes.Length < 1) return false;
			string categoryName = ((PerformanceCounterCategoryAttribute)attributes[0]).Name;

			bool result = false;
			try
			{
				if (PerformanceCounterCategory.Exists(categoryName))
				{
                    // get the category type
                    PerformanceCounterCategory category = new PerformanceCounterCategory(categoryName);
                    PerformanceCounterCategoryType categoryType = category.CategoryType;

					foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic))
					{
						// ignore member if it is not a performance counter or it is not static
						if (field.FieldType != typeof(PerformanceCounter) || (instance == null && !field.IsStatic)) continue;

						// get the performance counter attribute
						attributes = field.GetCustomAttributes(typeof(PerformanceCounterAttribute), false);
						// ignore it if it has no performance counter attribute set
						if (attributes.Length < 1) continue;

                        // get the counter attribute data
						PerformanceCounterAttribute counter = (PerformanceCounterAttribute)attributes[0];
                        // use a default instance name if the the counter does not have one and the category is marked MultiInstance
                        string instanceName = (counter.Instance == String.Empty && category.CategoryType == PerformanceCounterCategoryType.MultiInstance) ? "_default" : counter.Instance;
                        // assign the performance counter
						field.SetValue(instance, new PerformanceCounter(categoryName, counter.Name, instanceName, false));

						// create base counter if needed
						switch (counter.Type)
						{
							case PerformanceCounterType.AverageCount64:
							case PerformanceCounterType.RawFraction:
							case PerformanceCounterType.SampleFraction:
								FieldInfo baseCounter = type.GetField(field.Name + "Base", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
								if (baseCounter != null)
									baseCounter.SetValue(instance, new PerformanceCounter(categoryName, counter.Name + "Base", instanceName, false));
								break;
							default: break;
						}
					}
					result = true;
				}
			}
			catch (Exception)
			{
				result = false;
			}

			return result;
		}

		#endregion
	}
}

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)



Comments and Discussions