@@ -20,6 +20,19 @@ public static void ObserveDuration(this IValueObserver observer, Action method)
2020 }
2121 }
2222
23+ public static void ObserveDuration ( this IValueObserver observer , Action method , Action < Exception > onObserveException )
24+ {
25+ var ts = Stopwatch . GetTimestamp ( ) ;
26+ try
27+ {
28+ method ( ) ;
29+ }
30+ finally
31+ {
32+ ObserveHandlingException ( observer , GetDuration ( ts ) , onObserveException ) ;
33+ }
34+ }
35+
2336 public static T ObserveDuration < T > ( this IValueObserver observer , Func < T > method )
2437 {
2538 var ts = Stopwatch . GetTimestamp ( ) ;
@@ -33,6 +46,19 @@ public static T ObserveDuration<T>(this IValueObserver observer, Func<T> method)
3346 }
3447 }
3548
49+ public static T ObserveDuration < T > ( this IValueObserver observer , Func < T > method , Action < Exception > onObserveException )
50+ {
51+ var ts = Stopwatch . GetTimestamp ( ) ;
52+ try
53+ {
54+ return method ( ) ;
55+ }
56+ finally
57+ {
58+ ObserveHandlingException ( observer , GetDuration ( ts ) , onObserveException ) ;
59+ }
60+ }
61+
3662 public static async Task ObserveDurationAsync ( this IValueObserver observer , Func < Task > method )
3763 {
3864 var ts = Stopwatch . GetTimestamp ( ) ;
@@ -46,6 +72,19 @@ public static async Task ObserveDurationAsync(this IValueObserver observer, Func
4672 }
4773 }
4874
75+ public static async Task ObserveDurationAsync ( this IValueObserver observer , Func < Task > method , Action < Exception > onObserveException )
76+ {
77+ var ts = Stopwatch . GetTimestamp ( ) ;
78+ try
79+ {
80+ await method ( ) . ConfigureAwait ( false ) ;
81+ }
82+ finally
83+ {
84+ ObserveHandlingException ( observer , GetDuration ( ts ) , onObserveException ) ;
85+ }
86+ }
87+
4988 public static async Task < T > ObserveDurationAsync < T > ( this IValueObserver observer , Func < Task < T > > method )
5089 {
5190 var ts = Stopwatch . GetTimestamp ( ) ;
@@ -59,6 +98,19 @@ public static async Task<T> ObserveDurationAsync<T>(this IValueObserver observer
5998 }
6099 }
61100
101+ public static async Task < T > ObserveDurationAsync < T > ( this IValueObserver observer , Func < Task < T > > method , Action < Exception > onObserveException )
102+ {
103+ var ts = Stopwatch . GetTimestamp ( ) ;
104+ try
105+ {
106+ return await method ( ) . ConfigureAwait ( false ) ;
107+ }
108+ finally
109+ {
110+ ObserveHandlingException ( observer , GetDuration ( ts ) , onObserveException ) ;
111+ }
112+ }
113+
62114 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
63115 private static double GetDuration ( long startTs )
64116 {
@@ -67,4 +119,29 @@ private static double GetDuration(long startTs)
67119
68120 return elapsed / frequency ;
69121 }
122+
123+ private static void ObserveHandlingException ( IValueObserver observer , double duration , Action < Exception > onObserveException )
124+ {
125+ if ( onObserveException is null )
126+ {
127+ observer . Observe ( duration ) ;
128+ return ;
129+ }
130+
131+ try
132+ {
133+ observer . Observe ( duration ) ;
134+ }
135+ catch ( Exception ex )
136+ {
137+ try
138+ {
139+ onObserveException ( ex ) ;
140+ }
141+ catch
142+ {
143+ // Swallow exceptions from the handler so ObserveDuration* does not throw due to handler failures
144+ }
145+ }
146+ }
70147}
0 commit comments