-1

I am trying to trace metrics for .NET core application and libraries referenced. Metrics like: latency, throughput, count, size, ..etc.

For instance, say I am implementing latency metric, I will have to surround each method I want to calculate latency for as follows:

    var sw = Stopwatch.StartNew();
    var result = MyFunction(input1, input2, input3);
    sw.Stop();
    
    // set latency out
    latency = sw.ElapsedMilliseconds;
    return result;

I am trying to see if there is a cleaner way in C#. I thought of passing a delegate method and defining a function like this to avoid duplication of Stopwatch.StartNew() and sw.Stop()

 public static TResult CollectLatency<T, U, V,TResult>(Func<T, U, V, TResult> func, out long latency, T input1, U input2, V input3)
        {
            var sw = Stopwatch.StartNew();
            var result = func(input1, input2, input3);
            sw.Stop();
            
            // set latency out
            latency = sw.ElapsedMilliseconds;
            return result;
        }

but then I will have to define overloads of this method with different number of inputs depending on all the methods I want to measure latency against.

One solution I thought of was to have only one input and have all my methods to be measured only take one parameter ( a class reference type including all parameters). However, that is not an option since there are existing external consumers to these methods and will break them during upgrade.

Is there another solution I can explore?

Saher Ahwal
  • 9,015
  • 32
  • 84
  • 152

1 Answers1

2

You could pass parameters as closed variables, which eliminates the need to implement overloads for each type of parameters.

public static long CollectLatency(Action action)
{
    var sw = Stopwatch.StartNew();
    action();
    sw.Stop();
    return sw.ElapsedMilliseconds;
}

Then you'd call it like tis:

var latency = CollectLatency( () => MyFunction(input1, input2, input3) );

If you actually need the result and not just the latency, you can also collect that in a closed variable.

SomeType result;
var latency = CollectLatency( () => result = MyFunction(input1, input2, input3) );
John Wu
  • 50,556
  • 8
  • 44
  • 80