-
Notifications
You must be signed in to change notification settings - Fork 0
/
Stopwatch.cs
175 lines (143 loc) · 4.78 KB
/
Stopwatch.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
using System;
using System.Runtime.InteropServices;
namespace CopyDb
{
/// <summary>
/// Provides a set of methods and properties that you can use to accurately measure elapsed time.
/// Thanks Paul Welter (http://weblogs.asp.net/pwelter34).
/// </summary>
public struct Stopwatch
{
#region SafeNativeMethods
[DllImport ("kernel32.dll")]
private static extern bool QueryPerformanceFrequency (out long lpFrequency);
[DllImport ("kernel32.dll")]
private static extern bool QueryPerformanceCounter (out long lpPerformanceCount);
#endregion //SafeNativeMethods
#region Public Fields
/// <summary>Gets the frequency of the timer as the number of ticks per second. This field is read-only.</summary>
public static readonly long Frequency;
/// <summary>Indicates whether the timer is based on a high-resolution performance counter. This field is read-only.</summary>
public static readonly bool IsHighResolution;
#endregion //Public Fields
#region Private Fields
private long elapsed;
private bool isRunning;
private long startTimeStamp;
private static readonly double tickFrequency;
#endregion //Private Fields
#region Constructors
static Stopwatch ()
{
if (!QueryPerformanceFrequency(out Stopwatch.Frequency))
{
Stopwatch.IsHighResolution = false;
Stopwatch.Frequency = TimeSpan.TicksPerSecond;
Stopwatch.tickFrequency = 1;
}
else
{
Stopwatch.IsHighResolution = true;
Stopwatch.tickFrequency = TimeSpan.TicksPerSecond;
Stopwatch.tickFrequency /= ((double) Stopwatch.Frequency);
}
}
#endregion //Constructors
#region Private Methods
private long GetElapsedDateTimeTicks ()
{
long ticks = this.GetRawElapsedTicks();
if (Stopwatch.IsHighResolution)
{
double highTicks = ticks;
highTicks *= Stopwatch.tickFrequency;
return (long) highTicks;
}
return ticks;
}
private long GetRawElapsedTicks ()
{
long elapsedTimestamp = this.elapsed;
if (this.isRunning)
{
long currentTimestamp = Stopwatch.GetTimestamp();
long endTimestamp = currentTimestamp - this.startTimeStamp;
elapsedTimestamp += endTimestamp;
}
return elapsedTimestamp;
}
#endregion //Private Methods
#region Public Methods
/// <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>
public static long GetTimestamp ()
{
if (Stopwatch.IsHighResolution)
{
long ticks = 0;
QueryPerformanceCounter(out ticks);
return ticks;
}
return DateTime.UtcNow.Ticks;
}
/// <summary>Stops time interval measurement and resets the elapsed time to zero.</summary>
public void Reset ()
{
this.elapsed = 0;
this.isRunning = false;
this.startTimeStamp = 0;
}
/// <summary>Starts, or resumes, measuring elapsed time for an interval.</summary>
public void Start ()
{
if (!this.isRunning)
{
this.isRunning = true;
this.startTimeStamp = Stopwatch.GetTimestamp();
}
}
/// <summary>Initializes a new Stopwatch instance, sets the elapsed time property to zero, and starts measuring elapsed time.</summary>
/// <returns>A Stopwatch that has just begun measuring elapsed time.</returns>
public static Stopwatch StartNew ()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
return stopwatch;
}
/// <summary>Stops measuring elapsed time for an interval.</summary>
public void Stop ()
{
long currentTimestamp = Stopwatch.GetTimestamp();
if (this.isRunning)
{
long endTimestamp = currentTimestamp - this.startTimeStamp;
this.elapsed += endTimestamp;
this.isRunning = false;
}
}
#endregion //Public Methods
#region Public Properties
/// <summary>Gets the total elapsed time measured by the current instance.</summary>
/// <value>A read-only System.TimeSpan representing the total elapsed time measured by the current instance.</value>
public TimeSpan Elapsed
{
get {return new TimeSpan(this.GetElapsedDateTimeTicks());}
}
/// <summary>Gets the total elapsed time measured by the current instance, in milliseconds.</summary>
public long ElapsedMilliseconds
{
get {return (this.GetElapsedDateTimeTicks()/TimeSpan.TicksPerMillisecond);}
}
/// <summary>Gets the total elapsed time measured by the current instance, in timer ticks.</summary>
public long ElapsedTicks
{
get {return this.GetRawElapsedTicks();}
}
/// <summary>Gets a value indicating whether the Stopwatch timer is running.</summary>
public bool IsRunning
{
get {return this.isRunning;}
}
#endregion //Public Properties
}
}