0

Currently my code is decorated with a lot of code like this:

Stopwatch stopWatch = new Stopwatch(); stopWatch.Start();
InitializeComponent();
stopWatch.Stop(); App.CoHomeMSecs = stopWatch.ElapsedMilliseconds;

Although I realize there's not much code here is there any way I could reduce the code associated with initializing the stopwatch, starting, stopping and setting the value.

For example, could I put the process into a method that returned the milliseconds and that took a block of code as an argument?

Alan2
  • 23,493
  • 79
  • 256
  • 450
  • What are you looking for? – theMayer Feb 11 '20 at 05:23
  • To reduce the surrounding code that does the timing. In this case (and other cases), there is more timing code than code that is being timed. Would love it if there was a way to construct and start and if stop returned a time for example. – Alan2 Feb 11 '20 at 05:24
  • You could write a wrapper that executes an Action, returning elapsed milliseconds. – theMayer Feb 11 '20 at 05:25
  • This is what I was wondering about but I am not sure how I could code that. – Alan2 Feb 11 '20 at 05:25
  • 1
    I think this here is what you want: https://stackoverflow.com/a/37640207/1567352 – Brendan Green Feb 11 '20 at 05:38
  • Four great answers with upvotes and I get a downvote and one person wants to close the question. Some people here amaze me. Thanks to everyone who gave good answers. – Alan2 Feb 11 '20 at 10:50

4 Answers4

3

You can bake your own method, add pepper and salt to taste

public static long Time(Action action)
{
   var stopWatch =  Stopwatch.StartNew();
   action();
   return stopWatch.ElapsedMilliseconds;
}

Usage

Console.WriteLine(Time(() => Thread.Sleep(100)));

Output

100

Demo Here

TheGeneral
  • 79,002
  • 9
  • 103
  • 141
2

You could have a method declared in a static class which accepts your action, and times it.

using System;
using System.Diagnostics;

public static class MethodTimer
{
    public static double CalcTime(Action action)
    {
        var stopWatch = new Stopwatch();
        stopWatch.Start();
        action();
        stopWatch.Stop();

        return stopWatch.Elapsed.TotalMilliseconds;
    }
}

You'd use it like this:

var millis = MethodTimer.CalcTime(() => SomeMethod());
theMayer
  • 15,456
  • 7
  • 58
  • 90
2

I would highly recommend using an internet search engine. Anyway, here is the sample code:

var stopWatch = Stopwatch.StartNew();
InitializeComponent();
App.CoHomeMSecs = stopWatch.ElapsedMilliseconds;
Optional Option
  • 1,521
  • 13
  • 33
2

If the block of code that you want to measure is longer than one line of code, you could use a using block with a helper class like the following:

public class BlockTimer : IDisposable
{
    private readonly Stopwatch _stopwatch;
    private Action<long> _getMillisecondsFunc;

    public BlockTimer(Action<long> getMilliseconds)
    {
        _getMillisecondsFunc = getMilliseconds;

        _stopwatch = new Stopwatch();
        _stopwatch.Start();
    }

    public void Dispose()
    {
        _stopwatch.Stop();
        _getMillisecondsFunc(_stopwatch.ElapsedMilliseconds);
    }
}

Which can be used this way:

long duration;
using(new BlockTimer(t=>duration=t))
{
    // all
    // the code
    // I want 
    // to measure
}

At the end of the block, it will execute the action that you pass and you can assign easily it to a variable, log it, etc.

Francesc Castells
  • 2,692
  • 21
  • 25