private void Initialize(PerformanceCounterInputConfiguration configuration, IHealthReporter healthReporter)
        {
            this.syncObject               = new object();
            this.subject                  = new EventFlowSubject <EventData>();
            this.healthReporter           = healthReporter;
            this.processInstanceNameCache = new ProcessInstanceNameCache();
            this.sampleInterval           = TimeSpan.FromMilliseconds(configuration.SampleIntervalMsec);
            var currentProcess = Process.GetCurrentProcess();

            this.currentProcessName = currentProcess.ProcessName;
            this.currentProcessId   = currentProcess.Id;

            // The CLR Process ID counter used for process ID to counter instance name mapping for CLR counters will not read correctly
            // until at least one garbage collection is performed, so we will force one now.
            // The listener is usually created during service startup so the GC should not take very long.
            GC.Collect();

            this.trackedPerformanceCounters = new List <TrackedPerformanceCounter>();

            foreach (var counterConfiguration in configuration.Counters)
            {
                if (!counterConfiguration.Validate())
                {
                    healthReporter.ReportProblem($"{nameof(PerformanceCounterInput)}: configuration for counter {counterConfiguration.CounterName} is invalid");
                }
                else
                {
                    this.trackedPerformanceCounters.Add(new TrackedPerformanceCounter(counterConfiguration));
                }
            }

            this.collectionTimer = new Timer(this.DoCollection, null, this.sampleInterval, TimeSpan.FromDays(1));
        }
        public bool SampleNextValue(ProcessInstanceNameCache processInstanceNameCache, out float newValue)
        {
            Requires.NotNull(processInstanceNameCache, nameof(processInstanceNameCache));

            newValue = 0;
            if (disposed)
            {
                return(false);
            }

            var now = DateTimeOffset.UtcNow;

            if (now - this.lastAccessedOn < TimeSpan.FromMilliseconds(this.Configuration.SamplingIntervalMsec))
            {
                return(false);
            }

            string instanceName = processInstanceNameCache.GetCounterInstanceNameForCurrentProcess(this.Configuration);

            this.lastAccessedOn = now;
            if (this.counter == null || (!string.IsNullOrEmpty(instanceName) && instanceName != this.lastInstanceName))
            {
                if (this.counter != null)
                {
                    this.counter.Dispose();
                }
                this.counter = new PerformanceCounter(
                    this.Configuration.CounterCategory,
                    this.Configuration.CounterName,
                    instanceName,
                    readOnly: true);
            }
            this.lastInstanceName = instanceName;

            newValue = this.counter.NextValue();
            return(true);
        }