Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mjs3339
Created March 20, 2018 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjs3339/f1a83dc1b1feffc7ffeced1057aad61d to your computer and use it in GitHub Desktop.
Save mjs3339/f1a83dc1b1feffc7ffeced1057aad61d to your computer and use it in GitHub Desktop.
C# Stopwatch Class with Microseconds
public class StopwatchMs
{
private const long TicksPerMillisecond = 10000;
private const long TicksPerSecond = TicksPerMillisecond * 1000;
private const double TicksPerMicrosecond = 10;
public static readonly long Frequency;
public static readonly bool IsHighResolution;
private static readonly double tickFrequency;
private long elapsed;
private long startTimeStamp;
static StopwatchMs()
{
var succeeded = QueryPerformanceFrequency(out Frequency);
if (!succeeded)
{
IsHighResolution = false;
Frequency = TicksPerSecond;
tickFrequency = 1;
}
else
{
IsHighResolution = true;
tickFrequency = TicksPerSecond;
tickFrequency /= Frequency;
}
}
public StopwatchMs()
{
Reset();
}
public bool IsRunning { get; private set; }
public TicksToTime Elapsed => new TicksToTime(GetElapsedDateTimeTicks());
public long ElapsedMilliseconds => GetElapsedDateTimeTicks() / TicksPerMillisecond;
public long ElapsedMicroseconds => (long) (ElapsedTicks * TicksPerMicrosecond);
public long ElapsedTicks => GetRawElapsedTicks();
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(
out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(
out long lpFrequency);
public void Start()
{
if (!IsRunning)
{
startTimeStamp = GetTimestamp();
IsRunning = true;
}
}
public static StopwatchMs StartNew()
{
var s = new StopwatchMs();
s.Start();
return s;
}
public void Stop()
{
if (IsRunning)
{
var endTimeStamp = GetTimestamp();
var elapsedThisPeriod = endTimeStamp - startTimeStamp;
elapsed += elapsedThisPeriod;
IsRunning = false;
if (elapsed < 0)
elapsed = 0;
}
}
public void WaitMs(long us)
{
Start();
do
{
Thread.Sleep(0);
} while (ElapsedMicroseconds < us);
Stop();
}
public void Reset()
{
elapsed = 0;
IsRunning = false;
startTimeStamp = 0;
}
public void Restart()
{
elapsed = 0;
startTimeStamp = GetTimestamp();
IsRunning = true;
}
public static long GetTimestamp()
{
if (IsHighResolution)
{
long timestamp = 0;
QueryPerformanceCounter(out timestamp);
return timestamp;
}
return DateTime.UtcNow.Ticks;
}
private long GetRawElapsedTicks()
{
var timeElapsed = elapsed;
if (IsRunning)
{
var currentTimeStamp = GetTimestamp();
var elapsedUntilNow = currentTimeStamp - startTimeStamp;
timeElapsed += elapsedUntilNow;
}
return timeElapsed;
}
private long GetElapsedDateTimeTicks()
{
var rawTicks = GetRawElapsedTicks();
if (IsHighResolution)
{
double dticks = rawTicks;
dticks *= tickFrequency;
return unchecked((long) dticks);
}
return rawTicks;
}
public override string ToString()
{
return $"{Elapsed.Hours:00}:{Elapsed.Minutes:00}:{Elapsed.Seconds:00}:{Elapsed.Milliseconds:000}:{Elapsed.Microseconds:000}:";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment