PerformanceCounter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Monitoring / system / Diagnosticts / PerformanceCounter.cs / 1305376 / PerformanceCounter.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Diagnostics { 
    using System.Runtime.Serialization.Formatters; 
    using System.Runtime.InteropServices;
    using System.ComponentModel; 
    using System.Diagnostics;
    using System;
    using System.Collections;
    using System.Globalization; 
    using System.Security;
    using System.Security.Permissions; 
    using System.Runtime.CompilerServices; 
    using System.Runtime.ConstrainedExecution;
    using System.Threading; 


    /// 
    ///     Performance Counter component. 
    ///     This class provides support for NT Performance counters.
    ///     It handles both the existing counters (accesible by Perf Registry Interface) 
    ///     and user defined (extensible) counters. 
    ///     This class is a part of a larger framework, that includes the perf dll object and
    ///     perf service. 
    /// 
    [
    InstallerType("System.Diagnostics.PerformanceCounterInstaller," + AssemblyRef.SystemConfigurationInstall),
    SRDescription(SR.PerformanceCounterDesc), 
    HostProtection(Synchronization = true, SharedState = true)
    ] 
    public sealed class PerformanceCounter : Component, ISupportInitialize { 
        private string machineName;
        private string categoryName; 
        private string counterName;
        private string instanceName;
        private PerformanceCounterInstanceLifetime instanceLifetime = PerformanceCounterInstanceLifetime.Global;
 
        private bool isReadOnly;
        private bool initialized = false; 
        private string helpMsg = null; 
        private int counterType = -1;
 
        // Cached old sample
        private CounterSample oldSample = CounterSample.Empty;

        // Cached IP Shared Performanco counter 
        private SharedPerformanceCounter sharedCounter;
 
        [Obsolete("This field has been deprecated and is not used.  Use machine.config or an application configuration file to set the size of the PerformanceCounter file mapping.")] 
        public static int DefaultFileMappingSize = 524288;
 
        private Object m_InstanceLockObject;
        private Object InstanceLockObject {
            get {
                if (m_InstanceLockObject == null) { 
                    Object o = new Object();
                    Interlocked.CompareExchange(ref m_InstanceLockObject, o, null); 
                } 
                return m_InstanceLockObject;
            } 
        }

        /// 
        ///     The defaut constructor. Creates the perf counter object 
        /// 
        public PerformanceCounter() { 
            machineName = "."; 
            categoryName = String.Empty;
            counterName = String.Empty; 
            instanceName = String.Empty;
            this.isReadOnly = true;
            GC.SuppressFinalize(this);
        } 

        ///  
        ///     Creates the Performance Counter Object 
        /// 
        public PerformanceCounter(string categoryName, string counterName, string instanceName, string machineName) { 
            this.MachineName = machineName;
            this.CategoryName = categoryName;
            this.CounterName = counterName;
            this.InstanceName = instanceName; 
            this.isReadOnly = true;
            Initialize(); 
            GC.SuppressFinalize(this); 
        }
 
        internal PerformanceCounter(string categoryName, string counterName, string instanceName, string machineName, bool skipInit) {
            this.MachineName = machineName;
            this.CategoryName = categoryName;
            this.CounterName = counterName; 
            this.InstanceName = instanceName;
            this.isReadOnly = true; 
            this.initialized = true; 
            GC.SuppressFinalize(this);
        } 

        /// 
        ///     Creates the Performance Counter Object on local machine.
        ///  
        public PerformanceCounter(string categoryName, string counterName, string instanceName) :
        this(categoryName, counterName, instanceName, true) { 
        } 

        ///  
        ///     Creates the Performance Counter Object on local machine.
        /// 
        public PerformanceCounter(string categoryName, string counterName, string instanceName, bool readOnly) {
            this.MachineName = "."; 
            this.CategoryName = categoryName;
            this.CounterName = counterName; 
            this.InstanceName = instanceName; 
            this.isReadOnly = readOnly;
            Initialize(); 
            GC.SuppressFinalize(this);
        }

        ///  
        ///     Creates the Performance Counter Object, assumes that it's a single instance
        ///  
        public PerformanceCounter(string categoryName, string counterName) : 
        this(categoryName, counterName, true) {
        } 

        /// 
        ///     Creates the Performance Counter Object, assumes that it's a single instance
        ///  
        public PerformanceCounter(string categoryName, string counterName, bool readOnly) :
        this(categoryName, counterName, "", readOnly) { 
        } 

        ///  
        ///     Returns the performance category name for this performance counter
        /// 
        [
        ReadOnly(true), 
        DefaultValue(""),
        TypeConverter("System.Diagnostics.Design.CategoryValueConverter, " + AssemblyRef.SystemDesign), 
        SRDescription(SR.PCCategoryName), 
        SettingsBindable(true)
        ] 
        public string CategoryName {
            get {
                return categoryName;
            } 
            set {
                if (value == null) 
                    throw new ArgumentNullException("value"); 

                if (categoryName == null || String.Compare(categoryName, value, StringComparison.OrdinalIgnoreCase) != 0) { 
                    categoryName = value;
                    Close();
                }
            } 
        }
 
        ///  
        ///     Returns the description message for this performance counter
        ///  
        [
        ReadOnly(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        MonitoringDescription(SR.PC_CounterHelp) 
        ]
        public string CounterHelp { 
            get { 
                string currentCategoryName = categoryName;
                string currentMachineName = machineName; 

                PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, currentMachineName, currentCategoryName);
                permission.Demand();
                Initialize(); 

                if (helpMsg == null) 
                    helpMsg = PerformanceCounterLib.GetCounterHelp(currentMachineName, currentCategoryName, this.counterName); 

                return helpMsg; 
            }
        }

        ///  
        ///     Sets/returns the performance counter name for this performance counter
        ///  
        [ 
        ReadOnly(true),
        DefaultValue(""), 
        TypeConverter("System.Diagnostics.Design.CounterNameConverter, " + AssemblyRef.SystemDesign),
        SRDescription(SR.PCCounterName),
        SettingsBindable(true)
        ] 
        public string CounterName {
            get { 
                return counterName; 
            }
            set { 
                if (value == null)
                    throw new ArgumentNullException("value");

                if (counterName == null || String.Compare(counterName, value, StringComparison.OrdinalIgnoreCase) != 0) { 
                    counterName = value;
                    Close(); 
                } 
            }
        } 

        /// 
        ///     Sets/Returns the counter type for this performance counter
        ///  
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        MonitoringDescription(SR.PC_CounterType) 
        ]
        public PerformanceCounterType CounterType { 
            get {
                if (counterType == -1) {
                    string currentCategoryName = categoryName;
                    string currentMachineName = machineName; 

                    // This is the same thing that NextSample does, except that it doesn't try to get the actual counter 
                    // value.  If we wanted the counter value, we would need to have an instance name. 
                    PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, currentMachineName, currentCategoryName);
                    permission.Demand(); 

                    Initialize();
                    CategorySample categorySample = PerformanceCounterLib.GetCategorySample(currentMachineName, currentCategoryName);
                    CounterDefinitionSample counterSample = categorySample.GetCounterDefinitionSample(this.counterName); 
                    this.counterType = counterSample.CounterType;
                } 
 
                return(PerformanceCounterType) counterType;
            } 
        }

        [
            DefaultValue(PerformanceCounterInstanceLifetime.Global), 
            SRDescription(SR.PCInstanceLifetime),
        ] 
        public PerformanceCounterInstanceLifetime InstanceLifetime { 
            get { return instanceLifetime; }
            set { 
                if (value > PerformanceCounterInstanceLifetime.Process || value < PerformanceCounterInstanceLifetime.Global)
                    throw new ArgumentOutOfRangeException("value");

                if (initialized) 
                    throw new InvalidOperationException(SR.GetString(SR.CantSetLifetimeAfterInitialized));
 
                instanceLifetime = value; 
            }
        } 

        /// 
        ///     Sets/returns an instance name for this performance counter
        ///  
        [
        ReadOnly(true), 
        DefaultValue(""), 
        TypeConverter("System.Diagnostics.Design.InstanceNameConverter, " + AssemblyRef.SystemDesign),
        SRDescription(SR.PCInstanceName), 
        SettingsBindable(true)
        ]
        public string InstanceName {
            get { 
                return instanceName;
            } 
            set { 
                if (value == null && instanceName == null)
                    return; 

                if ((value == null && instanceName != null) ||
                      (value != null && instanceName == null) ||
                      String.Compare(instanceName, value, StringComparison.OrdinalIgnoreCase) != 0) { 
                    instanceName = value;
                    Close(); 
                } 
            }
        } 

        /// 
        ///     Returns true if counter is read only (system counter, foreign extensible counter or remote counter)
        ///  
        [
        Browsable(false), 
        DefaultValue(true), 
        MonitoringDescription(SR.PC_ReadOnly)
        ] 
        public bool ReadOnly {
            get {
                return isReadOnly;
            } 

            set { 
                if (value != this.isReadOnly) { 
                    this.isReadOnly = value;
                    Close(); 
                }
            }
        }
 

        ///  
        ///     Set/returns the machine name for this performance counter 
        /// 
        [ 
        Browsable(false),
        DefaultValue("."),
        SRDescription(SR.PCMachineName),
        SettingsBindable(true) 
        ]
        public string MachineName { 
            get { 
                return machineName;
            } 
            set {
                if (!SyntaxCheck.CheckMachineName(value))
                    throw new ArgumentException(SR.GetString(SR.InvalidParameter, "machineName", value));
 
                if (machineName != value) {
                    machineName = value; 
                    Close(); 
                }
            } 
        }

        /// 
        ///     Directly accesses the raw value of this counter.  If counter type is of a 32-bit size, it will truncate 
        ///     the value given to 32 bits.  This can be significantly more performant for scenarios where
        ///     the raw value is sufficient.   Note that this only works for custom counters created using 
        ///     this component,  non-custom counters will throw an exception if this property is accessed. 
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        MonitoringDescription(SR.PC_RawValue)
        ] 
        public long RawValue {
            get { 
                if (ReadOnly) { 
                    //No need to initialize or Demand, since NextSample already does.
                    return NextSample().RawValue; 
                }
                else {
                    Initialize();
 
                    return this.sharedCounter.Value;
                } 
            } 
            set {
                if (ReadOnly) 
                    ThrowReadOnly();

                Initialize();
 
                this.sharedCounter.Value = value;
            } 
        } 

        ///  
        /// 
        public void BeginInit() {
            this.Close();
        } 

        ///  
        ///     Frees all the resources allocated by this counter 
        /// 
        public void Close() { 
            this.helpMsg = null;
            this.oldSample = CounterSample.Empty;
            this.sharedCounter = null;
            this.initialized = false; 
            this.counterType = -1;
        } 
 
        /// 
        ///     Frees all the resources allocated for all performance 
        ///     counters, frees File Mapping used by extensible counters,
        ///     unloads dll's used to read counters.
        /// 
        public static void CloseSharedResources() { 
            PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, ".", "*");
            permission.Demand(); 
            PerformanceCounterLib.CloseAllLibraries(); 
        }
 
        /// 
        /// 
        /// 
        protected override void Dispose(bool disposing) { 
            // safe to call while finalizing or disposing
            // 
            if (disposing) { 
                //Dispose managed and unmanaged resources
                Close(); 
            }

            base.Dispose(disposing);
        } 

        ///  
        ///     Decrements counter by one using an efficient atomic operation. 
        /// 
        public long Decrement() { 
            if (ReadOnly)
                ThrowReadOnly();

            Initialize(); 

            return this.sharedCounter.Decrement(); 
        } 

        ///  
        /// 
        public void EndInit() {
            Initialize();
        } 

        ///  
        ///     Increments the value of this counter.  If counter type is of a 32-bit size, it'll truncate 
        ///     the value given to 32 bits. This method uses a mutex to guarantee correctness of
        ///     the operation in case of multiple writers. This method should be used with caution because of the negative 
        ///     impact on performance due to creation of the mutex.
        /// 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        public long IncrementBy(long value) { 
            if (isReadOnly)
                ThrowReadOnly(); 
 
            Initialize();
 
            return this.sharedCounter.IncrementBy(value);
        }

        ///  
        ///     Increments counter by one using an efficient atomic operation.
        ///  
        public long Increment() { 
            if (isReadOnly)
                ThrowReadOnly(); 

            Initialize();

            return this.sharedCounter.Increment(); 
        }
 
        private void ThrowReadOnly() { 
            throw new InvalidOperationException(SR.GetString(SR.ReadOnlyCounter));
        } 

        private void Initialize() {
            // Keep this method small so the JIT will inline it.
            if (!initialized && !DesignMode) { 
                InitializeImpl();
            } 
        } 

        ///  
        ///     Intializes required resources
        /// 
        //[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        private void InitializeImpl() { 
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try { 
                Monitor.Enter(InstanceLockObject, ref tookLock);
 
                if (!initialized) {
                    string currentCategoryName = categoryName;
                    string currentMachineName = machineName;
 
                    if (currentCategoryName == String.Empty)
                        throw new InvalidOperationException(SR.GetString(SR.CategoryNameMissing)); 
                    if (this.counterName == String.Empty) 
                        throw new InvalidOperationException(SR.GetString(SR.CounterNameMissing));
 
                    if (this.ReadOnly) {
                        PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, currentMachineName, currentCategoryName);

                        permission.Demand(); 

                        if (!PerformanceCounterLib.CounterExists(currentMachineName, currentCategoryName, counterName)) 
                            throw new InvalidOperationException(SR.GetString(SR.CounterExists, currentCategoryName, counterName)); 

                        PerformanceCounterCategoryType categoryType = PerformanceCounterLib.GetCategoryType(currentMachineName, currentCategoryName); 
                        if (categoryType == PerformanceCounterCategoryType.MultiInstance) {
                            if (String.IsNullOrEmpty(instanceName))
                                throw new InvalidOperationException(SR.GetString(SR.MultiInstanceOnly, currentCategoryName));
                        } else if (categoryType == PerformanceCounterCategoryType.SingleInstance) { 
                            if (!String.IsNullOrEmpty(instanceName))
                                throw new InvalidOperationException(SR.GetString(SR.SingleInstanceOnly, currentCategoryName)); 
                        } 

                        if (instanceLifetime != PerformanceCounterInstanceLifetime.Global) 
                            throw new InvalidOperationException(SR.GetString(SR.InstanceLifetimeProcessonReadOnly));

                        this.initialized = true;
                    } else { 
                        PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Write, currentMachineName, currentCategoryName);
                        permission.Demand(); 
 
                        if (currentMachineName != "." && String.Compare(currentMachineName, PerformanceCounterLib.ComputerName, StringComparison.OrdinalIgnoreCase) != 0)
                            throw new InvalidOperationException(SR.GetString(SR.RemoteWriting)); 

                        SharedUtils.CheckNtEnvironment();

                        if (!PerformanceCounterLib.IsCustomCategory(currentMachineName, currentCategoryName)) 
                            throw new InvalidOperationException(SR.GetString(SR.NotCustomCounter));
 
                        // check category type 
                        PerformanceCounterCategoryType categoryType = PerformanceCounterLib.GetCategoryType(currentMachineName, currentCategoryName);
                        if (categoryType == PerformanceCounterCategoryType.MultiInstance) { 
                            if (String.IsNullOrEmpty(instanceName))
                                throw new InvalidOperationException(SR.GetString(SR.MultiInstanceOnly, currentCategoryName));
                        } else if (categoryType == PerformanceCounterCategoryType.SingleInstance) {
                            if (!String.IsNullOrEmpty(instanceName)) 
                                throw new InvalidOperationException(SR.GetString(SR.SingleInstanceOnly, currentCategoryName));
                        } 
 
                        if (String.IsNullOrEmpty(instanceName) && InstanceLifetime == PerformanceCounterInstanceLifetime.Process)
                            throw new InvalidOperationException(SR.GetString(SR.InstanceLifetimeProcessforSingleInstance)); 

                        this.sharedCounter = new SharedPerformanceCounter(currentCategoryName.ToLower(CultureInfo.InvariantCulture), counterName.ToLower(CultureInfo.InvariantCulture), instanceName.ToLower(CultureInfo.InvariantCulture), instanceLifetime);
                        this.initialized = true;
                    } 
                }
            } finally { 
                if (tookLock) 
                    Monitor.Exit(InstanceLockObject);
            } 

        }

         // Will cause an update, raw value 
        /// 
        ///     Obtains a counter sample and returns the raw value for it. 
        ///  
        public CounterSample NextSample() {
            string currentCategoryName = categoryName; 
            string currentMachineName = machineName;

            PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, currentMachineName, currentCategoryName);
            permission.Demand(); 

            Initialize(); 
            CategorySample categorySample = PerformanceCounterLib.GetCategorySample(currentMachineName, currentCategoryName); 
            CounterDefinitionSample counterSample = categorySample.GetCounterDefinitionSample(this.counterName);
            this.counterType = counterSample.CounterType; 
            if (!categorySample.IsMultiInstance) {
                if (instanceName != null && instanceName.Length != 0)
                    throw new InvalidOperationException(SR.GetString(SR.InstanceNameProhibited, this.instanceName));
 
                return counterSample.GetSingleValue();
            } 
            else { 
                if (instanceName == null || instanceName.Length == 0)
                    throw new InvalidOperationException(SR.GetString(SR.InstanceNameRequired)); 

                return counterSample.GetInstanceValue(this.instanceName);
            }
        } 

        ///  
        ///     Obtains a counter sample and returns the calculated value for it. 
        ///     NOTE: For counters whose calculated value depend upon 2 counter reads,
        ///           the very first read will return 0.0. 
        /// 
        public float NextValue() {
            //No need to initialize or Demand, since NextSample already does.
            CounterSample newSample = NextSample(); 
            float retVal = 0.0f;
 
            retVal = CounterSample.Calculate(oldSample, newSample); 
            oldSample = newSample;
 
            return retVal;
        }

        ///  
        ///     Removes this counter instance from the shared memory
        ///  
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
        public void RemoveInstance() {
            if (isReadOnly) 
                throw new InvalidOperationException(SR.GetString(SR.ReadOnlyRemoveInstance));

            Initialize();
            sharedCounter.RemoveInstance(this.instanceName.ToLower(CultureInfo.InvariantCulture), instanceLifetime); 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Diagnostics { 
    using System.Runtime.Serialization.Formatters; 
    using System.Runtime.InteropServices;
    using System.ComponentModel; 
    using System.Diagnostics;
    using System;
    using System.Collections;
    using System.Globalization; 
    using System.Security;
    using System.Security.Permissions; 
    using System.Runtime.CompilerServices; 
    using System.Runtime.ConstrainedExecution;
    using System.Threading; 


    /// 
    ///     Performance Counter component. 
    ///     This class provides support for NT Performance counters.
    ///     It handles both the existing counters (accesible by Perf Registry Interface) 
    ///     and user defined (extensible) counters. 
    ///     This class is a part of a larger framework, that includes the perf dll object and
    ///     perf service. 
    /// 
    [
    InstallerType("System.Diagnostics.PerformanceCounterInstaller," + AssemblyRef.SystemConfigurationInstall),
    SRDescription(SR.PerformanceCounterDesc), 
    HostProtection(Synchronization = true, SharedState = true)
    ] 
    public sealed class PerformanceCounter : Component, ISupportInitialize { 
        private string machineName;
        private string categoryName; 
        private string counterName;
        private string instanceName;
        private PerformanceCounterInstanceLifetime instanceLifetime = PerformanceCounterInstanceLifetime.Global;
 
        private bool isReadOnly;
        private bool initialized = false; 
        private string helpMsg = null; 
        private int counterType = -1;
 
        // Cached old sample
        private CounterSample oldSample = CounterSample.Empty;

        // Cached IP Shared Performanco counter 
        private SharedPerformanceCounter sharedCounter;
 
        [Obsolete("This field has been deprecated and is not used.  Use machine.config or an application configuration file to set the size of the PerformanceCounter file mapping.")] 
        public static int DefaultFileMappingSize = 524288;
 
        private Object m_InstanceLockObject;
        private Object InstanceLockObject {
            get {
                if (m_InstanceLockObject == null) { 
                    Object o = new Object();
                    Interlocked.CompareExchange(ref m_InstanceLockObject, o, null); 
                } 
                return m_InstanceLockObject;
            } 
        }

        /// 
        ///     The defaut constructor. Creates the perf counter object 
        /// 
        public PerformanceCounter() { 
            machineName = "."; 
            categoryName = String.Empty;
            counterName = String.Empty; 
            instanceName = String.Empty;
            this.isReadOnly = true;
            GC.SuppressFinalize(this);
        } 

        ///  
        ///     Creates the Performance Counter Object 
        /// 
        public PerformanceCounter(string categoryName, string counterName, string instanceName, string machineName) { 
            this.MachineName = machineName;
            this.CategoryName = categoryName;
            this.CounterName = counterName;
            this.InstanceName = instanceName; 
            this.isReadOnly = true;
            Initialize(); 
            GC.SuppressFinalize(this); 
        }
 
        internal PerformanceCounter(string categoryName, string counterName, string instanceName, string machineName, bool skipInit) {
            this.MachineName = machineName;
            this.CategoryName = categoryName;
            this.CounterName = counterName; 
            this.InstanceName = instanceName;
            this.isReadOnly = true; 
            this.initialized = true; 
            GC.SuppressFinalize(this);
        } 

        /// 
        ///     Creates the Performance Counter Object on local machine.
        ///  
        public PerformanceCounter(string categoryName, string counterName, string instanceName) :
        this(categoryName, counterName, instanceName, true) { 
        } 

        ///  
        ///     Creates the Performance Counter Object on local machine.
        /// 
        public PerformanceCounter(string categoryName, string counterName, string instanceName, bool readOnly) {
            this.MachineName = "."; 
            this.CategoryName = categoryName;
            this.CounterName = counterName; 
            this.InstanceName = instanceName; 
            this.isReadOnly = readOnly;
            Initialize(); 
            GC.SuppressFinalize(this);
        }

        ///  
        ///     Creates the Performance Counter Object, assumes that it's a single instance
        ///  
        public PerformanceCounter(string categoryName, string counterName) : 
        this(categoryName, counterName, true) {
        } 

        /// 
        ///     Creates the Performance Counter Object, assumes that it's a single instance
        ///  
        public PerformanceCounter(string categoryName, string counterName, bool readOnly) :
        this(categoryName, counterName, "", readOnly) { 
        } 

        ///  
        ///     Returns the performance category name for this performance counter
        /// 
        [
        ReadOnly(true), 
        DefaultValue(""),
        TypeConverter("System.Diagnostics.Design.CategoryValueConverter, " + AssemblyRef.SystemDesign), 
        SRDescription(SR.PCCategoryName), 
        SettingsBindable(true)
        ] 
        public string CategoryName {
            get {
                return categoryName;
            } 
            set {
                if (value == null) 
                    throw new ArgumentNullException("value"); 

                if (categoryName == null || String.Compare(categoryName, value, StringComparison.OrdinalIgnoreCase) != 0) { 
                    categoryName = value;
                    Close();
                }
            } 
        }
 
        ///  
        ///     Returns the description message for this performance counter
        ///  
        [
        ReadOnly(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        MonitoringDescription(SR.PC_CounterHelp) 
        ]
        public string CounterHelp { 
            get { 
                string currentCategoryName = categoryName;
                string currentMachineName = machineName; 

                PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, currentMachineName, currentCategoryName);
                permission.Demand();
                Initialize(); 

                if (helpMsg == null) 
                    helpMsg = PerformanceCounterLib.GetCounterHelp(currentMachineName, currentCategoryName, this.counterName); 

                return helpMsg; 
            }
        }

        ///  
        ///     Sets/returns the performance counter name for this performance counter
        ///  
        [ 
        ReadOnly(true),
        DefaultValue(""), 
        TypeConverter("System.Diagnostics.Design.CounterNameConverter, " + AssemblyRef.SystemDesign),
        SRDescription(SR.PCCounterName),
        SettingsBindable(true)
        ] 
        public string CounterName {
            get { 
                return counterName; 
            }
            set { 
                if (value == null)
                    throw new ArgumentNullException("value");

                if (counterName == null || String.Compare(counterName, value, StringComparison.OrdinalIgnoreCase) != 0) { 
                    counterName = value;
                    Close(); 
                } 
            }
        } 

        /// 
        ///     Sets/Returns the counter type for this performance counter
        ///  
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        MonitoringDescription(SR.PC_CounterType) 
        ]
        public PerformanceCounterType CounterType { 
            get {
                if (counterType == -1) {
                    string currentCategoryName = categoryName;
                    string currentMachineName = machineName; 

                    // This is the same thing that NextSample does, except that it doesn't try to get the actual counter 
                    // value.  If we wanted the counter value, we would need to have an instance name. 
                    PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, currentMachineName, currentCategoryName);
                    permission.Demand(); 

                    Initialize();
                    CategorySample categorySample = PerformanceCounterLib.GetCategorySample(currentMachineName, currentCategoryName);
                    CounterDefinitionSample counterSample = categorySample.GetCounterDefinitionSample(this.counterName); 
                    this.counterType = counterSample.CounterType;
                } 
 
                return(PerformanceCounterType) counterType;
            } 
        }

        [
            DefaultValue(PerformanceCounterInstanceLifetime.Global), 
            SRDescription(SR.PCInstanceLifetime),
        ] 
        public PerformanceCounterInstanceLifetime InstanceLifetime { 
            get { return instanceLifetime; }
            set { 
                if (value > PerformanceCounterInstanceLifetime.Process || value < PerformanceCounterInstanceLifetime.Global)
                    throw new ArgumentOutOfRangeException("value");

                if (initialized) 
                    throw new InvalidOperationException(SR.GetString(SR.CantSetLifetimeAfterInitialized));
 
                instanceLifetime = value; 
            }
        } 

        /// 
        ///     Sets/returns an instance name for this performance counter
        ///  
        [
        ReadOnly(true), 
        DefaultValue(""), 
        TypeConverter("System.Diagnostics.Design.InstanceNameConverter, " + AssemblyRef.SystemDesign),
        SRDescription(SR.PCInstanceName), 
        SettingsBindable(true)
        ]
        public string InstanceName {
            get { 
                return instanceName;
            } 
            set { 
                if (value == null && instanceName == null)
                    return; 

                if ((value == null && instanceName != null) ||
                      (value != null && instanceName == null) ||
                      String.Compare(instanceName, value, StringComparison.OrdinalIgnoreCase) != 0) { 
                    instanceName = value;
                    Close(); 
                } 
            }
        } 

        /// 
        ///     Returns true if counter is read only (system counter, foreign extensible counter or remote counter)
        ///  
        [
        Browsable(false), 
        DefaultValue(true), 
        MonitoringDescription(SR.PC_ReadOnly)
        ] 
        public bool ReadOnly {
            get {
                return isReadOnly;
            } 

            set { 
                if (value != this.isReadOnly) { 
                    this.isReadOnly = value;
                    Close(); 
                }
            }
        }
 

        ///  
        ///     Set/returns the machine name for this performance counter 
        /// 
        [ 
        Browsable(false),
        DefaultValue("."),
        SRDescription(SR.PCMachineName),
        SettingsBindable(true) 
        ]
        public string MachineName { 
            get { 
                return machineName;
            } 
            set {
                if (!SyntaxCheck.CheckMachineName(value))
                    throw new ArgumentException(SR.GetString(SR.InvalidParameter, "machineName", value));
 
                if (machineName != value) {
                    machineName = value; 
                    Close(); 
                }
            } 
        }

        /// 
        ///     Directly accesses the raw value of this counter.  If counter type is of a 32-bit size, it will truncate 
        ///     the value given to 32 bits.  This can be significantly more performant for scenarios where
        ///     the raw value is sufficient.   Note that this only works for custom counters created using 
        ///     this component,  non-custom counters will throw an exception if this property is accessed. 
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        MonitoringDescription(SR.PC_RawValue)
        ] 
        public long RawValue {
            get { 
                if (ReadOnly) { 
                    //No need to initialize or Demand, since NextSample already does.
                    return NextSample().RawValue; 
                }
                else {
                    Initialize();
 
                    return this.sharedCounter.Value;
                } 
            } 
            set {
                if (ReadOnly) 
                    ThrowReadOnly();

                Initialize();
 
                this.sharedCounter.Value = value;
            } 
        } 

        ///  
        /// 
        public void BeginInit() {
            this.Close();
        } 

        ///  
        ///     Frees all the resources allocated by this counter 
        /// 
        public void Close() { 
            this.helpMsg = null;
            this.oldSample = CounterSample.Empty;
            this.sharedCounter = null;
            this.initialized = false; 
            this.counterType = -1;
        } 
 
        /// 
        ///     Frees all the resources allocated for all performance 
        ///     counters, frees File Mapping used by extensible counters,
        ///     unloads dll's used to read counters.
        /// 
        public static void CloseSharedResources() { 
            PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, ".", "*");
            permission.Demand(); 
            PerformanceCounterLib.CloseAllLibraries(); 
        }
 
        /// 
        /// 
        /// 
        protected override void Dispose(bool disposing) { 
            // safe to call while finalizing or disposing
            // 
            if (disposing) { 
                //Dispose managed and unmanaged resources
                Close(); 
            }

            base.Dispose(disposing);
        } 

        ///  
        ///     Decrements counter by one using an efficient atomic operation. 
        /// 
        public long Decrement() { 
            if (ReadOnly)
                ThrowReadOnly();

            Initialize(); 

            return this.sharedCounter.Decrement(); 
        } 

        ///  
        /// 
        public void EndInit() {
            Initialize();
        } 

        ///  
        ///     Increments the value of this counter.  If counter type is of a 32-bit size, it'll truncate 
        ///     the value given to 32 bits. This method uses a mutex to guarantee correctness of
        ///     the operation in case of multiple writers. This method should be used with caution because of the negative 
        ///     impact on performance due to creation of the mutex.
        /// 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        public long IncrementBy(long value) { 
            if (isReadOnly)
                ThrowReadOnly(); 
 
            Initialize();
 
            return this.sharedCounter.IncrementBy(value);
        }

        ///  
        ///     Increments counter by one using an efficient atomic operation.
        ///  
        public long Increment() { 
            if (isReadOnly)
                ThrowReadOnly(); 

            Initialize();

            return this.sharedCounter.Increment(); 
        }
 
        private void ThrowReadOnly() { 
            throw new InvalidOperationException(SR.GetString(SR.ReadOnlyCounter));
        } 

        private void Initialize() {
            // Keep this method small so the JIT will inline it.
            if (!initialized && !DesignMode) { 
                InitializeImpl();
            } 
        } 

        ///  
        ///     Intializes required resources
        /// 
        //[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        private void InitializeImpl() { 
            bool tookLock = false;
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try { 
                Monitor.Enter(InstanceLockObject, ref tookLock);
 
                if (!initialized) {
                    string currentCategoryName = categoryName;
                    string currentMachineName = machineName;
 
                    if (currentCategoryName == String.Empty)
                        throw new InvalidOperationException(SR.GetString(SR.CategoryNameMissing)); 
                    if (this.counterName == String.Empty) 
                        throw new InvalidOperationException(SR.GetString(SR.CounterNameMissing));
 
                    if (this.ReadOnly) {
                        PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, currentMachineName, currentCategoryName);

                        permission.Demand(); 

                        if (!PerformanceCounterLib.CounterExists(currentMachineName, currentCategoryName, counterName)) 
                            throw new InvalidOperationException(SR.GetString(SR.CounterExists, currentCategoryName, counterName)); 

                        PerformanceCounterCategoryType categoryType = PerformanceCounterLib.GetCategoryType(currentMachineName, currentCategoryName); 
                        if (categoryType == PerformanceCounterCategoryType.MultiInstance) {
                            if (String.IsNullOrEmpty(instanceName))
                                throw new InvalidOperationException(SR.GetString(SR.MultiInstanceOnly, currentCategoryName));
                        } else if (categoryType == PerformanceCounterCategoryType.SingleInstance) { 
                            if (!String.IsNullOrEmpty(instanceName))
                                throw new InvalidOperationException(SR.GetString(SR.SingleInstanceOnly, currentCategoryName)); 
                        } 

                        if (instanceLifetime != PerformanceCounterInstanceLifetime.Global) 
                            throw new InvalidOperationException(SR.GetString(SR.InstanceLifetimeProcessonReadOnly));

                        this.initialized = true;
                    } else { 
                        PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Write, currentMachineName, currentCategoryName);
                        permission.Demand(); 
 
                        if (currentMachineName != "." && String.Compare(currentMachineName, PerformanceCounterLib.ComputerName, StringComparison.OrdinalIgnoreCase) != 0)
                            throw new InvalidOperationException(SR.GetString(SR.RemoteWriting)); 

                        SharedUtils.CheckNtEnvironment();

                        if (!PerformanceCounterLib.IsCustomCategory(currentMachineName, currentCategoryName)) 
                            throw new InvalidOperationException(SR.GetString(SR.NotCustomCounter));
 
                        // check category type 
                        PerformanceCounterCategoryType categoryType = PerformanceCounterLib.GetCategoryType(currentMachineName, currentCategoryName);
                        if (categoryType == PerformanceCounterCategoryType.MultiInstance) { 
                            if (String.IsNullOrEmpty(instanceName))
                                throw new InvalidOperationException(SR.GetString(SR.MultiInstanceOnly, currentCategoryName));
                        } else if (categoryType == PerformanceCounterCategoryType.SingleInstance) {
                            if (!String.IsNullOrEmpty(instanceName)) 
                                throw new InvalidOperationException(SR.GetString(SR.SingleInstanceOnly, currentCategoryName));
                        } 
 
                        if (String.IsNullOrEmpty(instanceName) && InstanceLifetime == PerformanceCounterInstanceLifetime.Process)
                            throw new InvalidOperationException(SR.GetString(SR.InstanceLifetimeProcessforSingleInstance)); 

                        this.sharedCounter = new SharedPerformanceCounter(currentCategoryName.ToLower(CultureInfo.InvariantCulture), counterName.ToLower(CultureInfo.InvariantCulture), instanceName.ToLower(CultureInfo.InvariantCulture), instanceLifetime);
                        this.initialized = true;
                    } 
                }
            } finally { 
                if (tookLock) 
                    Monitor.Exit(InstanceLockObject);
            } 

        }

         // Will cause an update, raw value 
        /// 
        ///     Obtains a counter sample and returns the raw value for it. 
        ///  
        public CounterSample NextSample() {
            string currentCategoryName = categoryName; 
            string currentMachineName = machineName;

            PerformanceCounterPermission permission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, currentMachineName, currentCategoryName);
            permission.Demand(); 

            Initialize(); 
            CategorySample categorySample = PerformanceCounterLib.GetCategorySample(currentMachineName, currentCategoryName); 
            CounterDefinitionSample counterSample = categorySample.GetCounterDefinitionSample(this.counterName);
            this.counterType = counterSample.CounterType; 
            if (!categorySample.IsMultiInstance) {
                if (instanceName != null && instanceName.Length != 0)
                    throw new InvalidOperationException(SR.GetString(SR.InstanceNameProhibited, this.instanceName));
 
                return counterSample.GetSingleValue();
            } 
            else { 
                if (instanceName == null || instanceName.Length == 0)
                    throw new InvalidOperationException(SR.GetString(SR.InstanceNameRequired)); 

                return counterSample.GetInstanceValue(this.instanceName);
            }
        } 

        ///  
        ///     Obtains a counter sample and returns the calculated value for it. 
        ///     NOTE: For counters whose calculated value depend upon 2 counter reads,
        ///           the very first read will return 0.0. 
        /// 
        public float NextValue() {
            //No need to initialize or Demand, since NextSample already does.
            CounterSample newSample = NextSample(); 
            float retVal = 0.0f;
 
            retVal = CounterSample.Calculate(oldSample, newSample); 
            oldSample = newSample;
 
            return retVal;
        }

        ///  
        ///     Removes this counter instance from the shared memory
        ///  
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
        public void RemoveInstance() {
            if (isReadOnly) 
                throw new InvalidOperationException(SR.GetString(SR.ReadOnlyRemoveInstance));

            Initialize();
            sharedCounter.RemoveInstance(this.instanceName.ToLower(CultureInfo.InvariantCulture), instanceLifetime); 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK