Introduction
In many cases as programmers develop their applications sometimes they need to know the time that some of code blocks takes to execute. One of the old school ways is to use TickCount
s. In this article we use the same trick but in a more user-friendly way.
An improvement I have made in this approach is that the output of result (elapsed time) will show in a proper way! automatically or with a callBackFunction
.
Used Namespaces
This class uses three namespaces' functionalities:
using System;
using System.Diagnostics;
using System.IO;
About the code
The implemented class is inherited from IDispose
interface. which applies Disposal
attribute to our class that has a great part in this class:
class Measurment : IDisposable
The c
onstructor
of this class has two overrides:
public Measurment(Action<TimeSpan> callBackFunction);
public Measurment();
The main one takes an delegate predefined in mscorlib.dll
signatured as:
public delegate void Action<in T>(T obj);
So the client code can either initialize delegate for callBackFunction
:
protected Action<TimeSpan> callBackFunction { get; set; }
In order to calling when the code blocks region is over and pass throw the elapsed time to callBackFunction
at the disposal of the Measurment
's object or not ( uses the other constructor ).
In both way the class initialize its callBackFunction
.
The c
onstructor
with no argument will initialize the
callBackFunction as follow:
public Measurment() :
this((time) =>
{
if (Console.In != StreamReader.Null)
{
Console.WriteLine(String.Format("Estimated elapsed time : {0}", time));
}
else
{
try
{
String tmpPath = Path.GetTempFileName() + ".bat";
using (StreamWriter sw = new StreamWriter(
new FileStream(
tmpPath,
FileMode.Create,
FileAccess.Write,
FileShare.None
)
)
)
{
sw.WriteLine(
String.Format("@echo off
\r\n echo Estimated elapsed time : {0}
\r\n echo.
\r\n echo.
\r\n pause", time)
);
}
Process.Start(tmpPath).WaitForExit();
File.Delete(tmpPath);
}
catch { }
}
})
{}
The constructor
will send a
Lambda Expression[^] to the other constructor in order to setting callBackFunction
.
The main
constructor of the class(the one with parameter) handles the class' initialization:
public Measurment(Action<TimeSpan> callBackFunction)
{
if (callBackFunction == null)
throw new ArgumentNullException("callBackFunction",
"this param. cannot be null.");
this.callBackFunction = callBackFunction;
startTick = Environment.TickCount;
}
Note:
The function that send as delegate should signature has as follow :
void callBackFunction(TimeSpan elapsedTime);
And at the end we have the Dispose function(the implementation of IDisposable
interface).
At the Dispose function we calculate the elapsed time since the constructor has called till the class' object's disposal, then the created TimeSpan
object will send to the callBackFunction
.
public void Dispose()
{
int tot = Environment.TickCount - startTick;
if (callBackFunction != null)
callBackFunction(new TimeSpan(tot * 10000));
}
About the used Lambda Expression
This Lambda Expression does a smart calculation to determine the best way to show the result depended on the running application type.
- If the running program is a console program so for simply output the result on console
if (Console.In != StreamReader.Null)
{
Console.WriteLine(String.Format("Estimated elapsed time : {0}", time));
}
- Otherwise the program create a
temp batch file
in Windows' Temp Folder
and launches that batch file in order to indicate the elapsed time.
try
{
String tmpPath = Path.GetTempFileName() + ".bat";
using (StreamWriter sw = new StreamWriter(
new FileStream(
tmpPath,
FileMode.Create,
FileAccess.Write,
FileShare.None
)
)
)
{
sw.WriteLine(
String.Format("@echo off
\r\n echo Estimated elapsed time : {0}
\r\n echo.
\r\n echo.
\r\n pause", time));
}
Process.Start(tmpPath).WaitForExit();
File.Delete(tmpPath);
}
catch { }
Using the code
This class calculates the elapse time since the class' object has created till it's Disposal.
In order to take full advantage of this functionality any code blocks goes between the Measure's object creation till its Dispose()
function call the performance will be measured.
This is a sample usage of the Measure
class:
static class Test
{
static void Main(string[] args)
{
using (new Measurment())
{
System.Threading.Thread.Sleep(2000);
}
Console.ReadKey(true);
}
}
This should calculate the time approximately 2 seconds(The sleep function does not sleep exactly the given time to sleep).
Points of Interest
This class uses the old school trick to measure the elapse time for executing code blocks in proper and in a handy way.