|
using System;
using System.Data;
using System.Configuration;
using System.Diagnostics;
namespace DiagnosticTools
{
/// <summary>
/// Method definition for having the log information handled in a custom way.
/// </summary>
/// <param name="isEnd">True if the task is ending. False if the task is starting.</param>
/// <param name="taskName">The name of the task.</param>
/// <param name="category">The category of the task.</param>
/// <param name="elapsedTime">The elapsed time for the task when ending. If the task is just starting then a blank TimeSpan is provided and should be disregarded.</param>
public delegate void CustomLog(bool isEnd, string taskName, string category, TimeSpan elapsedTime);
/// <summary>
/// A class for doing simple and straight forward performance monitoring.
/// Designed to be very easy to drop in, use, and remove.
/// When used in a debug session in the IDE, the information will be written to the
/// Output tab in the Debug section.
/// </summary>
/// <remarks>
/// To enable this in an ASP.NET web service, some changes to the web.config file are required.
/// </remarks>
/// <example>
/// An example of a simple use.
/// <code>
/// using (new SimpleTimer("Write invoice to DB"))
/// {
/// // task to measure performance on.
/// }
/// </code>
/// This example shows how it can be nested.
/// <code>
/// using (new SimpleTimer("Top Level Task 1"))
/// {
/// // Some code that may take time
///
/// using (new SimpleTimer("Nested Task 2"))
/// {
/// // task to measure performance on.
/// }
/// }
/// </code>
/// </example>
public class SimpleTimer : IDisposable
{
#region Private Members
private string _TaskName;
private string _Category;
//http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx
private Stopwatch _Stopwatch = new Stopwatch();
private CustomLog _LoggingMethod;
#endregion
#region Constructors
/// <summary>
/// Start a timer with a task name assigned.
/// </summary>
/// <param name="taskName">The name of the task being measured.</param>
public SimpleTimer(string taskName) : this(taskName, null) { }
/// <summary>
/// Start a timer with a task name assigned.
/// </summary>
/// <param name="taskName">The name of the task being measured.</param>
/// <param name="category">The category or group name for the task.</param>
public SimpleTimer(string taskName, string category) : this(taskName, category, null) { }
/// <summary>
/// Start a timer with a task name assigned.
/// </summary>
/// <param name="taskName">The name of the task being measured.</param>
/// <param name="category">The category or group name for the task.</param>
/// <param name="log">The delegated method to log information to.</param>
public SimpleTimer(string taskName, string category, CustomLog log)
{
if (String.IsNullOrEmpty(taskName))
throw new ArgumentException("taskName is null or empty.", "taskName");
_TaskName = taskName;
// Use "SimpleTimer" if they don't provide a category to use.
_Category = (String.IsNullOrEmpty(category))? "SimpleTimer" : category;
// Use default Trace logging if one isn't provided.
_LoggingMethod = (log != null)? log : TraceLog;
// Notify that the task is about to begin.
_LoggingMethod(false, _TaskName, _Category, new TimeSpan());
_Stopwatch.Start();
}
#endregion
#region Properties
/// <summary>
/// Get the text description of the task being timed.
/// </summary>
public string TaskName
{
get
{
return _TaskName;
}
}
/// <summary>
/// Get the category assigned for the timer.
/// </summary>
public string Category
{
get
{
return _Category;
}
}
#endregion
#region IDisposable Members
/// <summary>
/// Stops the timer and outputs the information.
/// </summary>
public void Dispose()
{
StopTimerAndOutput();
}
#endregion
#region Private Methods
// Default handler for logging information to the "Trace" output.
private void TraceLog(bool isEnd, string taskName, string category, TimeSpan elapsedTime)
{
if (isEnd)
{
Trace.Unindent();
// Record the time formatted in milliseconds
string timeText = String.Format("{0} msec", elapsedTime.TotalMilliseconds);
// Write out that the closing information with time details
Trace.WriteLine(String.Format("{0} - End - ({1})", taskName, timeText), category);
// Ensure the data is written out
Trace.Flush();
}
// else is start
else
{
// Write out that we are starting
Trace.WriteLine(String.Format("{0} - Start", taskName), category);
Trace.Indent();
}
}
/// <summary>
/// Stop the timer and write out the information on elapsed time.
/// </summary>
private void StopTimerAndOutput()
{
// First, stop the timer.
_Stopwatch.Stop();
// Notify that the task has ended and pass in the elapsed time.
_LoggingMethod(true, _TaskName, _Category, _Stopwatch.Elapsed);
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Mark Ericksen is a Senior Developer, Technical Lead, Architect and more. He is passionate about technology, photography, and continually learning.