Imran Rizvi
Imran Rizvi

Reputation: 7438

How to write generic code to get time taken by a method execution in c#

I need to log time taken by various methods , code blocks in my enterprise server application I am using Stopwatch as of now , sample code what I've implemented is as below:

var sw = new Stopwatch();
sw.Start();
DoSomething();
sw.Stop();
logManager.LogInformation(String.Format("Time taken by DoSomething function is {0} ms.", sw.ElapsedMilliseconds));

I am writing like this at many places in many .cs files, I just wanted to reduce this manual work by writing one common method or extension for measuring time taken. For this I am thinking to Wrap my actual method with the time measuring method like:

long elapsedMilliseconds = ExecuteAndGetTimeTaken(this.DoSomething());

Or generic extension methods like

long elapsedMilliseconds = this.DoSomething().GetTimeTaken();

It will be great if the method log the message with time taken too e.g.

long elapsedMilliseconds = ExecuteAndGetTimeTaken(this.DoSomething(),logManager,message);

How to write common class / method or extensions to solve the purpose?

Upvotes: 0

Views: 2025

Answers (2)

user287107
user287107

Reputation: 9417

I created once a short class, which can be used in a using statement. one other advantage is, that if an exception is thrown, also the time is measured

/// <summary>
/// Provides a easy to use timer. 
/// Usage
/// using(new DiagnosticTimer())
/// {
///     // do anything
/// }
/// </summary>
public class DiagnosticTimer : IDisposable
{
    public System.Diagnostics.Stopwatch StopWatch { get; protected set; }
    public string Message { get; set; }

    public DiagnosticTimer()
    {
        Message = "Diagnostic Timer at " + new System.Diagnostics.StackTrace().GetFrame(1).ToString();
        StopWatch = new System.Diagnostics.Stopwatch();
        StopWatch.Start();
    }
    public DiagnosticTimer(string Message)
    {
        this.Message = Message;
        StopWatch = new System.Diagnostics.Stopwatch();
        StopWatch.Start();
    }

    public void Dispose()
    {
        StopWatch.Stop();
        System.Diagnostics.Trace.WriteLine(Message + StopWatch.Elapsed.ToString());
    }

}

Upvotes: 2

CSharpie
CSharpie

Reputation: 9467

This should do:

void ExecuteAndMeasureTimeTaken(Action action, string message)
{
    if(action == null) throw new ArgumentNullException();
    else
    {
        var sw = new Stopwatch();
        sw.Start();

        action();

        sw.Stop(); 

        LogMessage(message , sw.ElapsedMilliseconds);
    }
}

Call it like this:

logManager.ExecuteAndMeasureTimeTaken(() => GC.Collect(), "Time taken by GC after each Listning is {0} ms.");

Doest it really need a LogManager parameter?

If so, you may add this to your LogManager itself.

Upvotes: 7

Related Questions