Skip to content

Commit a8c2a7e

Browse files
authored
Merge pull request #59 from LeeCampbell/RecordScope
RecordScope extension method.
2 parents 1d516f9 + ded0cd5 commit a8c2a7e

2 files changed

Lines changed: 60 additions & 6 deletions

File tree

HdrHistogram.UnitTests/Recording/RecorderTestsBase.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Threading.Tasks;
23
using HdrHistogram.Utilities;
34
using Xunit;
45

@@ -22,9 +23,9 @@ public void ConstructorShouldRejectInvalidParameters(
2223
long lowestTrackableValue, long highestTrackableValue, int numberOfSignificantValueDigits,
2324
string errorParamName, string errorMessage)
2425
{
25-
var ex = Assert.Throws<ArgumentException>(() =>
26-
Create(lowestTrackableValue,
27-
highestTrackableValue,
26+
var ex = Assert.Throws<ArgumentException>(() =>
27+
Create(lowestTrackableValue,
28+
highestTrackableValue,
2829
numberOfSignificantValueDigits));
2930
Assert.Equal(errorParamName, ex.ParamName);
3031
Assert.StartsWith(errorMessage, ex.Message);
@@ -183,7 +184,7 @@ public void RecordValueWithExpectedInterval()
183184
public void RecordAction_increments_TotalCount()
184185
{
185186
var recorder = Create(DefautltLowestDiscernibleValue, DefaultHighestTrackableValue, DefaultSignificantFigures);
186-
187+
187188
recorder.Record(() => { });
188189

189190
var longHistogram = recorder.GetIntervalHistogram();
@@ -233,9 +234,9 @@ public void GetIntervalHistogramInto_copies_data_over_provided_Histogram()
233234
recorder.RecordValue(1000);
234235
recorder.RecordValue(10000);
235236
recorder.RecordValue(100000);
236-
237+
237238
recorder.GetIntervalHistogramInto(targetHistogram);
238-
239+
239240
Assert.Equal(3, targetHistogram.TotalCount);
240241
Assert.Equal(0, targetHistogram.GetCountAtValue(1));
241242
Assert.Equal(0, targetHistogram.GetCountAtValue(10));
@@ -259,5 +260,14 @@ public void Using_external_histogram_for_recycling_throws()
259260

260261
recorder.GetIntervalHistogramInto(externallyCreatedHistogram);
261262
}
263+
264+
[Fact]
265+
public void RecordScope_increments_TotalCount()
266+
{
267+
var recorder = Create(DefautltLowestDiscernibleValue, DefaultHighestTrackableValue, DefaultSignificantFigures);
268+
using (recorder.RecordScope()) { }
269+
var histogram = recorder.GetIntervalHistogram();
270+
Assert.Equal(1, histogram.TotalCount);
271+
}
262272
}
263273
}

HdrHistogram/HistogramExtensions.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,5 +206,49 @@ public static void Record(this IRecorder recorder, Action action)
206206
var elapsed = Stopwatch.GetTimestamp() - start;
207207
recorder.RecordValue(elapsed);
208208
}
209+
210+
/// <summary>
211+
/// Records the elapsed time till the returned token is disposed.
212+
/// This can be useful to testing large blocks of code, or wrapping around and <c>await</c> clause.
213+
/// </summary>
214+
/// <param name="recorder">The <see cref="IRecorder"/> instance to record the latency in.</param>
215+
/// <returns>Returns a token to be disposed once the scope </returns>
216+
/// <remarks>
217+
/// This can be helpful for recording a scope of work.
218+
/// It also has the benefit of allowing a simple way to record an awaitable method.
219+
/// <example>
220+
/// This example shows how an awaitable method can be cleanly instrumented using C# using scope.
221+
/// <code>
222+
/// using(recorder.RecordScope())
223+
/// {
224+
/// await SomeExpensiveCall();
225+
/// }
226+
/// </code>
227+
/// </example>
228+
/// It should be noted that this method returns a token and as such allocates an object.
229+
/// This should taken into consideration, specifically the cost of the allocation and GC would affect the program.
230+
/// </remarks>
231+
public static IDisposable RecordScope(this IRecorder recorder)
232+
{
233+
return new Timer(recorder);
234+
}
235+
236+
private sealed class Timer : IDisposable
237+
{
238+
private readonly IRecorder _recorder;
239+
private readonly long _start;
240+
241+
public Timer(IRecorder recorder)
242+
{
243+
_recorder = recorder;
244+
_start = Stopwatch.GetTimestamp();
245+
}
246+
247+
public void Dispose()
248+
{
249+
var elapsed = Stopwatch.GetTimestamp() - _start;
250+
_recorder.RecordValue(elapsed);
251+
}
252+
}
209253
}
210254
}

0 commit comments

Comments
 (0)