'16/12/2004 - Daniel Moth creates Stopwatch (http://www.danielmoth.com/Blog/)
Namespace System.Diagnostics
Public Class Stopwatch
#Region "Public Statics"
'''
''' Indicates whether the timer is based on a high-resolution performance counter. This field is read-only.
'''
Public Shared ReadOnly IsHighResolution As Boolean
'''
''' Gets the current number of ticks in the timer mechanism.
'''
''' A long integer representing the tick counter value of the underlying timer mechanism.
Public Shared Function GetTimeStamp() As Int64
Dim perfCount As Int64
QueryPerformanceCounter(perfCount)
Return perfCount
End Function
'''
''' Initializes a new Stopwatch instance, sets the elapsed time property to zero, and starts measuring elapsed time.
'''
''' A Stopwatch that has just begun measuring elapsed time.
Public Shared Function StartNew() As Stopwatch
Dim sw As New Stopwatch
sw.Start()
Return sw
End Function
'''
''' Gets the frequency of the timer as the number of ticks per second. This field is read-only.
'''
Public Shared ReadOnly Frequency As Int64
#End Region
#Region "Public Interface"
'''
''' Initializes a new instance of the Stopwatch class.
'''
Public Sub New()
If IsHighResolution = False Then
Throw New Exception("Stopwatch class. Try a device that supports high frequency timer. On current device use Environment.TickCount instead.")
End If
End Sub
'''
''' Stops time interval measurement and resets the elapsed time to zero.
'''
Public Sub Reset()
mElapsed = 0 'ticks
mIsRunning = False
mStartPerfCount = 0
End Sub
'''
''' Starts, or resumes, measuring elapsed time for an interval.
'''
Public Sub Start()
If mIsRunning Then
Return
End If
mStartPerfCount = Stopwatch.GetTimeStamp()
mIsRunning = True
End Sub
'''
''' Gets a value indicating whether the Stopwatch timer is running.
'''
Public ReadOnly Property IsRunning() As Boolean
Get
Return mIsRunning
End Get
End Property
'''
''' Stops measuring elapsed time for an interval.
'''
Public Sub [Stop]()
If Not mIsRunning Then
Return
End If
mElapsed = Me.ElapsedTicks()
mIsRunning = False
End Sub
'''
''' Gets the total elapsed time measured by the current instance.
''' Throws InvalidOperationException if the timer is not stopped prior to the call.
'''
Public ReadOnly Property Elapsed() As TimeSpan
Get
Return New TimeSpan(Me.GetAdjustedTicks)
End Get
End Property
'''
''' Gets the total elapsed time measured by the current instance, in milliseconds.
''' Throws InvalidOperationException if the timer is not stopped prior to the call.
'''
Public ReadOnly Property ElapsedMilliseconds() As Int64
Get
Return (GetAdjustedTicks() \ MILLIS_IN_TICKS)
End Get
End Property
'''
''' Gets the total elapsed time measured by the current instance, in timer ticks.
''' Throws InvalidOperationException if the timer is not stopped prior to the call.
'''
Public ReadOnly Property ElapsedTicks() As Int64
Get
If Not mIsRunning Then
Return mElapsed
End If
Return (mElapsed + GetTimeStamp() - mStartPerfCount)
End Get
End Property
#End Region
#Region "Privates"
Shared Sub New()
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncfhowto/html/uperfcoun.asp
Dim freq As Int64
If QueryPerformanceFrequency(freq) = 0 Then
Stopwatch.IsHighResolution = False
Return
End If
IsHighResolution = True
Stopwatch.Frequency = freq
'ticks per second = (10000 ticks per millisecond * 1000)
smFreqInTicks = ((MILLIS_IN_TICKS * 1000) / freq)
End Sub
Private Function GetAdjustedTicks() As Int64
Dim temp As Double = Me.ElapsedTicks
temp *= smFreqInTicks
Return CType(Math.Round(temp), Int64)
End Function
Private Shared ReadOnly smFreqInTicks As Double
Private mElapsed As Int64
Private mIsRunning As Boolean
Private mStartPerfCount As Int64
Private Const MILLIS_IN_TICKS As Int64 = 10000
#End Region
#Region "PInvokes"
' Extract from my Win32Api class
#If FULL_FRAME = True Then
Private Const DllName2 As String = "kernel32.dll"
#Else
Private Const DllName2 As String = "coredll.dll"
#End If
_
Friend Shared Function QueryPerformanceCounter(ByRef perfCounter As Int64) As Integer
End Function
_
Friend Shared Function QueryPerformanceFrequency(ByRef frequency As Int64) As Integer
End Function
#End Region
End Class
End Namespace