Results 1 to 10 of 10

Thread: MicroTimer, Resource Friendly Accurate Timer

Threaded View

  1. #10

    Thread Starter
    Member
    Join Date
    Oct 2016
    Posts
    32

    Re: MicroTimer, Resource Friendly Accurate Timer

    As suggested here is the source:
    Code:
    Imports System.Runtime.InteropServices
    Imports System.Threading
    
    Public Class MicroTimer
    
        Public Shared Event Elapsed()
    
    #Region "Misc"
        Public Shared Function TicksPerYoctosecond() As Decimal
            Return Stopwatch.Frequency / 1000000000000000000000000D
        End Function
    
        Public Shared Function TicksPerZeptosecond() As Decimal
            Return Stopwatch.Frequency / 1000000000000000000000D
        End Function
    
        Public Shared Function TicksPerAttosecond() As Decimal
            Return Stopwatch.Frequency / 1000000000000000000D
        End Function
    
        Public Shared Function TicksPerFemtosecond() As Decimal
            Return Stopwatch.Frequency / 1000000000000000D
        End Function
    
        Public Shared Function TicksPerPicosecond() As Decimal
            Return Stopwatch.Frequency / 1000000000000D
        End Function
    
        Public Shared Function TicksPerNanosecond() As Decimal
            Return Stopwatch.Frequency / 1000000000D
        End Function
    
        Public Shared Function TicksPerMicrosecond() As Decimal
            Return Stopwatch.Frequency / 1000000D
        End Function
    
        Private Shared _TicksPerMillisecond As Decimal = Stopwatch.Frequency / 1000D
        Public Shared Function TicksPerMillisecond() As Decimal
            Return _TicksPerMillisecond
        End Function
    
        Public Shared Function TicksPerSecond() As Decimal
            Return Stopwatch.Frequency
        End Function
    
        Public Shared Function TicksPerMinute() As Decimal
            Return Stopwatch.Frequency * 60D
        End Function
    
        Public Shared Function TicksPerHour() As Decimal
            Return Stopwatch.Frequency * 3600D
        End Function
    
        Public Shared Function TicksPerDay() As Decimal
            Return Stopwatch.Frequency * 86400D
        End Function
    
        Public Shared Function TicksPerWeek() As Decimal
            Return Stopwatch.Frequency * 604800D
        End Function
    
        Public Shared Function TicksPerMonth() As Decimal
            Return Stopwatch.Frequency * 2592000D
        End Function
    
        Public Shared Function TicksPerYear() As Decimal
            Return Stopwatch.Frequency * 31536000D
        End Function
    #End Region
    
        <DllImport("winmm.dll")>
        Private Shared Function timeBeginPeriod(ByVal msec As UInteger) As MMRESULT
        End Function
        <DllImport("winmm.dll")>
        Private Shared Function timeEndPeriod(ByVal msec As UInteger) As MMRESULT
        End Function
        <DllImport("winmm.dll")>
        Private Shared Function timeSetEvent(ByVal delay As UInteger, ByVal resolution As UInteger,
                                             ByVal handler As TimerEventDel, ByVal user As IntPtr,
                                             ByVal eventType As UInteger) As MMRESULT
        End Function
        <DllImport("winmm.dll")>
        Private Shared Function timeKillEvent(ByVal id As UInteger) As MMRESULT
        End Function
    
        Private Delegate Sub TimerEventDel(ByVal id As UInteger,
                                           ByVal msg As UInteger,
                                           ByVal user As IntPtr,
                                           ByVal dw1 As IntPtr,
                                           ByVal dw2 As IntPtr)
    
        Private Shared mHandler As New TimerEventDel(Sub(ByVal id As UInteger,
                                                         ByVal msg As UInteger,
                                                         ByVal user As IntPtr,
                                                         ByVal dw1 As IntPtr,
                                                         ByVal dw2 As IntPtr)
                                                         timeKillEvent(id)
                                                         wh.Set()
                                                     End Sub)
    
        Private Shared wh As New AutoResetEvent(False)
        Private Shared wThread As Thread = Nothing
        Private Shared I As Integer = 0
        Private Shared NextTime As Decimal
        Private Shared Mode As Integer
        Private Shared _TicksPerInterval As Decimal
    
        Public Enum TimerMode As Integer
            Poll = -1
            Efficient = 0
        End Enum
    
        Private Enum MMRESULT
            MMSYSERR_NOERROR = 0
            MMSYSERR_ERROR = 1
            MMSYSERR_BADDEVICEID = 2
            MMSYSERR_NOTENABLED = 3
            MMSYSERR_ALLOCATED = 4
            MMSYSERR_INVALHANDLE = 5
            MMSYSERR_NODRIVER = 6
            MMSYSERR_NOMEM = 7
            MMSYSERR_NOTSUPPORTED = 8
            MMSYSERR_BADERRNUM = 9
            MMSYSERR_INVALFLAG = 10
            MMSYSERR_INVALPARAM = 11
            MMSYSERR_HANDLEBUSY = 12
            MMSYSERR_INVALIDALIAS = 13
            MMSYSERR_BADDB = 14
            MMSYSERR_KEYNOTFOUND = 15
            MMSYSERR_READERROR = 16
            MMSYSERR_WRITEERROR = 17
            MMSYSERR_DELETEERROR = 18
            MMSYSERR_VALNOTFOUND = 19
            MMSYSERR_NODRIVERCB = 20
            WAVERR_BADFORMAT = 32
            WAVERR_STILLPLAYING = 33
            WAVERR_UNPREPARED = 34
        End Enum
    
        Public Shared Sub SetStart(ByVal Ticks As Long, Optional ByVal Mode As TimerMode = TimerMode.Efficient)
            If Ticks > 0 Then
                Interlocked.Exchange(_TicksPerInterval, Ticks)
                Interlocked.Exchange(MicroTimer.Mode, Mode)
                If wThread Is Nothing Then CreateStartThread()
            End If
        End Sub
    
        Public Shared Sub SetStart(ByVal Ticks As Long, ByVal Precision As Integer)
            If Precision < 0 Then Throw New ArgumentOutOfRangeException(Precision, "Value must be of integer type greater than or equal to 0")
            If Ticks > 0 Then
                Interlocked.Exchange(_TicksPerInterval, Ticks)
                Interlocked.Exchange(Mode, Precision)
                If wThread Is Nothing Then CreateStartThread()
            End If
        End Sub
    
        Public Shared Sub SetStart(ByVal Rate As Decimal, Optional ByVal Mode As TimerMode = TimerMode.Efficient)
            If Rate > 0 Then
                Interlocked.Exchange(_TicksPerInterval, Stopwatch.Frequency / Rate)
                Interlocked.Exchange(MicroTimer.Mode, Mode)
                If wThread Is Nothing Then CreateStartThread()
            End If
        End Sub
    
        Public Shared Sub SetStart(ByVal Rate As Decimal, ByVal Precision As Integer)
            If Precision < 0 Then Throw New ArgumentOutOfRangeException(Precision, "Value must be of integer type greater than or equal to 0")
            If Rate > 0 Then
                Interlocked.Exchange(_TicksPerInterval, Stopwatch.Frequency / Rate)
                Interlocked.Exchange(Mode, Precision)
                If wThread Is Nothing Then CreateStartThread()
            End If
        End Sub
    
        Private Shared Sub CreateStartThread()
            wThread = New Thread(Sub()
                                     NextTime = Stopwatch.GetTimestamp
                                     While True
                                         If Mode > -1 Then
                                             If Mode = TimerMode.Efficient _
                                                Then I = (NextTime - Stopwatch.GetTimestamp) / _TicksPerMillisecond _
                                                Else I = Math.Round(((NextTime - Stopwatch.GetTimestamp) / _TicksPerMillisecond) - Mode)
                                             If I > 1 Then
                                                 timeSetEvent(I, 0, mHandler, IntPtr.Zero, 0)
                                                 wh.WaitOne()
                                             End If
                                         End If
                                         While Stopwatch.GetTimestamp < NextTime : End While
                                         Do
                                             RaiseEvent Elapsed()
                                             NextTime += GetTicksPerInterval()
                                         Loop While NextTime < Stopwatch.GetTimestamp
                                     End While
                                 End Sub) With {.Priority = ThreadPriority.Highest, .IsBackground = True}
            wThread.Start()
        End Sub
    
        Public Shared Function GetTicksPerInterval() As Decimal
            Return _TicksPerInterval
        End Function
    End Class
    The reason initially why I didn't paste the source is because I thought that if I ever wanted to make changes I only had to edit from one location but I guess you have a point with the potential reliability of pastebin or lack thereof.
    Last edited by TizzyT; Mar 22nd, 2017 at 12:25 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width