Skip to content

Instantly share code, notes, and snippets.

@ChrisMcKee
Created March 7, 2018 10:36
Show Gist options
  • Save ChrisMcKee/fa81cf5f4055f1fc2f90a5a2f427e846 to your computer and use it in GitHub Desktop.
Save ChrisMcKee/fa81cf5f4055f1fc2f90a5a2f427e846 to your computer and use it in GitHub Desktop.
using Microsoft.Win32;
using System;
namespace System.Diagnostics
{
/// <summary>
/// Provides a set of methods and properties that you can use to accurately measure elapsed time.
/// </summary>
/// <filterpriority>1</filterpriority>
public class Stopwatch
{
private const long TicksPerMillisecond = 10000L;
private const long TicksPerSecond = 10000000L;
private long elapsed;
private long startTimeStamp;
private bool isRunning;
/// <summary>
/// Gets the frequency of the timer as the number of ticks per second. This field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
public readonly static long Frequency;
/// <summary>
/// Indicates whether the timer is based on a high-resolution performance counter. This field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
public readonly static bool IsHighResolution;
private readonly static double tickFrequency;
/// <summary>
/// Gets the total elapsed time measured by the current instance.
/// </summary>
/// <returns>
/// A read-only <see cref="T:System.TimeSpan" /> representing the total elapsed time measured by the current instance.
/// </returns>
/// <filterpriority>1</filterpriority>
public TimeSpan Elapsed
{
get
{
return new TimeSpan(this.GetElapsedDateTimeTicks());
}
}
/// <summary>
/// Gets the total elapsed time measured by the current instance, in milliseconds.
/// </summary>
/// <returns>
/// A read-only long integer representing the total number of milliseconds measured by the current instance.
/// </returns>
/// <filterpriority>1</filterpriority>
public long ElapsedMilliseconds
{
get
{
return this.GetElapsedDateTimeTicks() / (long)10000;
}
}
/// <summary>
/// Gets the total elapsed time measured by the current instance, in timer ticks.
/// </summary>
/// <returns>
/// A read-only long integer representing the total number of timer ticks measured by the current instance.
/// </returns>
/// <filterpriority>1</filterpriority>
public long ElapsedTicks
{
get
{
return this.GetRawElapsedTicks();
}
}
/// <summary>
/// Gets a value indicating whether the <see cref="T:System.Diagnostics.Stopwatch" /> timer is running.
/// </summary>
/// <returns>true if the <see cref="T:System.Diagnostics.Stopwatch" /> instance is currently running and measuring elapsed time for an interval; otherwise, false.
/// </returns>
/// <filterpriority>1</filterpriority>
public bool IsRunning
{
get
{
return this.isRunning;
}
}
static Stopwatch()
{
if (!SafeNativeMethods.QueryPerformanceFrequency(out Stopwatch.Frequency))
{
Stopwatch.IsHighResolution = false;
Stopwatch.Frequency = (long)10000000;
Stopwatch.tickFrequency = 1;
return;
}
Stopwatch.IsHighResolution = true;
Stopwatch.tickFrequency = 10000000;
Stopwatch.tickFrequency /= (double)Stopwatch.Frequency;
}
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Diagnostics.Stopwatch" /> class.
/// </summary>
public Stopwatch()
{
this.Reset();
}
private long GetElapsedDateTimeTicks()
{
long rawElapsedTicks = this.GetRawElapsedTicks();
if (!Stopwatch.IsHighResolution)
{
return rawElapsedTicks;
}
return (long)((double)rawElapsedTicks * Stopwatch.tickFrequency);
}
private long GetRawElapsedTicks()
{
long timestamp = this.elapsed;
if (this.isRunning)
{
timestamp = timestamp + (Stopwatch.GetTimestamp() - this.startTimeStamp);
}
return timestamp;
}
/// <summary>
/// Gets the current number of ticks in the timer mechanism.
/// </summary>
/// <returns>
/// A long integer representing the tick counter value of the underlying timer mechanism.
/// </returns>
/// <filterpriority>1</filterpriority>
public static long GetTimestamp()
{
if (!Stopwatch.IsHighResolution)
{
return DateTime.UtcNow.Ticks;
}
long num = (long)0;
SafeNativeMethods.QueryPerformanceCounter(out num);
return num;
}
/// <summary>
/// Stops time interval measurement and resets the elapsed time to zero.
/// </summary>
/// <filterpriority>1</filterpriority>
public void Reset()
{
this.elapsed = (long)0;
this.isRunning = false;
this.startTimeStamp = (long)0;
}
/// <summary>
/// Starts, or resumes, measuring elapsed time for an interval.
/// </summary>
/// <filterpriority>1</filterpriority>
public void Start()
{
if (!this.isRunning)
{
this.startTimeStamp = Stopwatch.GetTimestamp();
this.isRunning = true;
}
}
/// <summary>
/// Initializes a new <see cref="T:System.Diagnostics.Stopwatch" /> instance, sets the elapsed time property to zero, and starts measuring elapsed time.
/// </summary>
/// <returns>
/// A <see cref="T:System.Diagnostics.Stopwatch" /> that has just begun measuring elapsed time.
/// </returns>
/// <filterpriority>1</filterpriority>
public static Stopwatch StartNew()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
return stopwatch;
}
/// <summary>
/// Stops measuring elapsed time for an interval.
/// </summary>
/// <filterpriority>1</filterpriority>
public void Stop()
{
if (this.isRunning)
{
this.elapsed += Stopwatch.GetTimestamp() - this.startTimeStamp;
this.isRunning = false;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment