public override void Increment(TelemetryData data, int amount) { ThrowIfDisposed(); if (!_started) { return; } if (data == null) { throw new ArgumentNullException("data"); } if (data.CounterType == TelemetryDataType.ElapsedTime) { throw new ArgumentException("Cannot use Increment() with TelemetryDataType.ElapsedTime, use StopwatchToggle() instead."); } // This restriction (TelmetryData must be declared in a derived class) effectively limits our ability to change telemetry storage // because a derived class is defined (for example Bsa.Hardware.DeviceTelemetry) then a more derived class cannot change its storage // without breaking all the code the used declared counters in base class. If it will ever be an issue then this restriction may be relaxed // or declaration and storage may be further decoupled. PerformanceCounterHolder holder; if (!_telemetryData.TryGetValue(data, out holder)) { throw new ArgumentException("Unknown telemetry data, only data declared in this session can be used.", "data"); } if (holder.IsDisabled) { return; } // Micro-optimization but Increment() is slightly faster than IncrementBy(), it's little but it's better to don't waste too much // time just for instrumentation (we don't know in which context this method will be called). if (amount == 1) { holder.Counter.Increment(); } else { holder.Counter.IncrementBy(amount); } if (data.CounterType == TelemetryDataType.AverageCount) { holder.Base.Increment(); } }
private void ThrowIfInvalidData(TelemetryData data) { ThrowIfDisposed(); if (!_started) { return; } if (data == null) { throw new ArgumentNullException("data"); } if (!_telemetryData.Contains(data)) { throw new ArgumentException("Unknown telemetry data, only data declared in this session can be used.", "data"); } }
public bool TryGetValue(TelemetryData data, out PerformanceCounterHolder value) { if (!_telemetryData.TryGetValue(data, out value)) { return(false); } // PerformanceCounterHolder exists but it's disabled, there is no need to // (try to) create an instance of its associated PC(s). if (value.IsDisabled) { return(true); } // If caller requested this PerformanceCounterHolder then it will use it, // it's the right moment to (lazy) create required instances. Note that // in this way performance penality for this operation is spanned across program // execution, it's a drawback but it speed-up initialization time (especially if there are // many mostly unused PCs). LazyCreatePerformanceCounter(value, data); return(true); }
public override void ToggleStopwatch(TelemetryData data) { ThrowIfDisposed(); if (!_started) { return; } if (data == null) { throw new ArgumentNullException("data"); } if (data.CounterType != TelemetryDataType.ElapsedTime) { throw new ArgumentException("You can use StopwatchToggle() only with TelemetryDataType.ElapsedTime, use Increment() for the other counters."); } // This restriction (TelmetryData must be declared in a derived class) effectively limits our ability to change telemetry storage // because a derived class is defined (for example Bsa.Hardware.DeviceTelemetry) then a more derived class cannot change its storage // without breaking all the code the used declared counters in base class. If it will ever be an issue then this restriction may be relaxed // or declaration and storage may be further decoupled. PerformanceCounterHolder holder; if (!_telemetryData.TryGetValue(data, out holder)) { throw new ArgumentException("Unknown telemetry data, only data declared in this session can be used.", "data"); } if (holder.IsDisabled) { return; } holder.Counter.RawValue = Stopwatch.GetTimestamp(); }
private static void LazyCreatePerformanceCounter(PerformanceCounterHolder holder, TelemetryData data) { if (holder.Counter != null) { return; } // If counter does not exist then it's probably an installation problem: // * counters have not been created and TelemetrySession.Start did it but OS didn't refresh them yet; // * category already existed but a new version added more counters and old category has not been properly uninstalled. if (!PerformanceCounterCategory.CounterExists(data.Name, data.Category)) { holder.IsDisabled = true; return; } holder.Counter = new PerformanceCounter(data.Category, data.Name, false); if (data.CounterType == TelemetryDataType.AverageCount) { // Base PC name convention: keep in sync with code in WpcTelemetrySessionInstaller holder.Base = new PerformanceCounter(data.Category, data.Name + "Base", false); holder.Counter.RawValue = 0; holder.Base.RawValue = 0; } }
/// <summary> /// Increment the value of the specified counter. /// </summary> /// <param name="data">The counter that should be incremented by the given value.</param> /// <param name="amount">Amount of the increment.</param> /// <exception cref="ArgumentNullException"> /// If <paramref name="data"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// If <paramref name="data"/> is of type <see cref="TelemetryDataType.ElapsedTime"/> (<see cref="ToggleStopwatch"/> should be used instead). /// <br/>-or-<br/> /// If <paramref name="data"/> is not a counter registered for this object. /// </exception> /// <remarks> /// If collection has not been started, it's stopped or specified counter is not accessible in the current data storage then /// value is simply silently discarded. /// </remarks> public abstract void Increment(TelemetryData data, int amount);
/// <summary> /// Start/stop collecting data for a counter that measures elapsed time to complete an operation. /// </summary> /// <param name="data">The counter that stores information about elapsed time to complete an operation.</param> /// <exception cref="ArgumentNullException"> /// If <paramref name="data"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// If <paramref name="data"/> is not of type <see cref="TelemetryDataType.ElapsedTime"/> (<see cref="Increment"/> should be used instead). /// <br/>-or-<br/> /// If <paramref name="data"/> is not a counter registered for this object. /// </exception> /// <remarks> /// If collection has not been started, it's stopped or specified counter is not accessible in the current data storage then /// value is simply silently discarded. /// </remarks> public abstract void ToggleStopwatch(TelemetryData data);