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();
            }
        }
示例#2
0
        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;
            }
        }
示例#6
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);
示例#7
0
 /// <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);