/// <summary>
 /// Aggregates the current statistics with another statistics counter.
 /// </summary>
 /// <param name="other">The other counter to aggregate with the current instance.</param>
 /// <returns>Current instance, summarized with the given statistics.</returns>
 public Statistics SummarizeWith(Statistics other)
 {
     if (other != null)
     {
         this._StartTick = Math.Min(this._StartTick, other._StartTick);
         this._EndTick = Math.Max(this._EndTick, other._EndTick);
         this._RequestCount += other._RequestCount;
         this._ResponseCount += other._ResponseCount;
         this._FailureCount += other._FailureCount;
         this._TimeoutCount += other._TimeoutCount;
         this._AbortCount += other._AbortCount;
         this._MinimumLatency = Math.Min(this._MinimumLatency, other._MinimumLatency);
         this._MaximumLatency = Math.Max(this._MaximumLatency, other._MaximumLatency);
         this._TotalExecutionDuration += other._TotalExecutionDuration;
         for (byte i = 0; i < 9; i++)
             this._LatencyBucketCount[i] += other._LatencyBucketCount[i];
         this._BytesSent += other._BytesSent;
         this._BytesReceived += other._BytesReceived;
     }
     return this;
 }
        /// <summary>
        /// Creates a frozen snapshot of the statistics counter - this is the state under which counters will be
        /// provided by the connection.
        /// </summary>
        /// <returns>Deep copy of the source.</returns>
        internal Statistics Snapshot()
        {
            // The future copy
            Statistics copy = null;

            // Wait for writers to complete
            while (this.WriteLock > 0) ;

            // Wait for other snapshots to complete
            while (this.SnapshotLock > 0) ;

            try
            {
                // Increment the snapshot lock so writers know to wait
                Interlocked.Increment(ref this.SnapshotLock);

                // Make the copy - there are no writers on the object right now, so the snapshot should be consistent
                // (don't really need interlocked access either as it is, since we're in snapshot lock, but it doesn't
                // hurt to stay safe...)
                copy = new Statistics();
                copy._StartTick = Interlocked.Read(ref this._StartTick);
                copy._EndTick = copy._EndTick == 0 ? Stopwatch.GetTimestamp() : Interlocked.Read(ref this._EndTick);
                copy._RequestCount = Interlocked.Read(ref this._RequestCount);
                copy._ResponseCount = Interlocked.Read(ref this._ResponseCount);
                copy._FailureCount = Interlocked.Read(ref this._FailureCount);
                copy._TimeoutCount = Interlocked.Read(ref this._TimeoutCount);
                copy._AbortCount = Interlocked.Read(ref this._AbortCount);
                copy._MinimumLatency = Interlocked.Read(ref this._MinimumLatency);
                copy._MaximumLatency = Interlocked.Read(ref this._MaximumLatency);
                copy._TotalExecutionDuration = Interlocked.Read(ref this._TotalExecutionDuration);
                for (byte i = 0; i < 9; i++)
                    copy._LatencyBucketCount[i] = Interlocked.Read(ref this._LatencyBucketCount[i]);
                copy._BytesSent = Interlocked.Read(ref this._BytesSent);
                copy._BytesReceived = Interlocked.Read(ref this._BytesReceived);

                // If the counter was never updated, those will have startup values - fix that.
                if (copy._MinimumLatency == long.MaxValue) copy._MinimumLatency = 0;
                if (copy._MaximumLatency == long.MinValue) copy._MaximumLatency = 0;
            }
            finally
            {
                // Decrement the snapshot lock.
                Interlocked.Decrement(ref this.SnapshotLock);
            }
            return copy;
        }
Beispiel #3
0
 /// <summary>
 /// Aggregate multiple counters with the current instance.
 /// </summary>
 /// <param name="others">List of counters to aggregate to the current instance.</param>
 /// <returns>Current instance, summarized with the given statistics.</returns>
 public Statistics SummarizeWith(IEnumerable <Statistics> others)
 {
     return(this.SummarizeWith(Statistics.Summarize(others)));
 }