Advertisement
TizzyT

BetterMicroTimer -TizzyT

Mar 19th, 2017
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 5.76 KB | None | 0 0
  1. Imports System.Runtime.InteropServices
  2. Imports System.Threading
  3.  
  4. Public Class MicroTimer
  5.     Public Shared Event Elapsed()
  6.  
  7.     Private Const TwoThirds As Decimal = 2D / 3D
  8.     Private Shared ReadOnly MicroRunning As New Mutex(True)
  9.     Private Shared ReadOnly MicroWait As New AutoResetEvent(False)
  10.     Private Shared ReadOnly WaitThread As Thread
  11.     Private Shared TicksPerMillisecond As Decimal = Stopwatch.Frequency / 1000D
  12.     Private Shared TicksPerInterval As Decimal
  13.     Private Shared NextTime As Decimal
  14.     Private Shared Milliseconds As Integer = 0
  15.     Private Shared Running As Boolean = False
  16.  
  17.     Shared Sub New()
  18.         WaitThread = New Thread(Sub()
  19.                                     While True
  20.                                         MicroRunning.WaitOne() 'Waits until the MicroTimer is started
  21.                                         Milliseconds = Math.Round(((NextTime - Stopwatch.GetTimestamp) / TicksPerMillisecond) - TwoThirds) 'Computes the number of milliseconds to wait (for efficiency)
  22.                                         If Milliseconds > 1 Then 'If the computed milliseconds to wait is greater than 1
  23.                                             timeSetEvent(Milliseconds, 0,
  24.                                                          New TimerEventDel(Sub(ByVal id As UInteger, ByVal msg As UInteger, ByVal user As IntPtr, ByVal dw1 As IntPtr, ByVal dw2 As IntPtr)
  25.                                                                                MicroWait.Set() 'Continue the while loop
  26.                                                                                Do : Loop Until timeKillEvent(id) = MMRESULT.MMSYSERR_NOERROR 'Keep trying to kill this event
  27.                                                                            End Sub),
  28.                                                          IntPtr.Zero, 0)
  29.                                             MicroWait.WaitOne() 'Wait a number of whole milliseconds before starting the sub millisecond poll
  30.                                         End If
  31.                                         While Stopwatch.GetTimestamp < NextTime : End While 'Spin until the next fire time is reached
  32.                                         Do
  33.                                             RaiseEvent Elapsed() 'Fire elapsed event
  34.                                             NextTime += TicksPerInterval 'Increments the NextTime by the interval amount
  35.                                         Loop While Running AndAlso NextTime < Stopwatch.GetTimestamp 'As long as the timer is behind it will keep firing until it is caught up
  36.                                         MicroRunning.ReleaseMutex()
  37.                                     End While
  38.                                 End Sub) With {.Priority = ThreadPriority.Highest, .IsBackground = True}
  39.         WaitThread.Start()
  40.     End Sub
  41.  
  42.     Public Shared Sub Start()
  43.         Running = True
  44.         NextTime = Stopwatch.GetTimestamp 'Computes the next time the MicroTimer will fire
  45.         MicroRunning.ReleaseMutex()
  46.     End Sub
  47.     Public Shared Sub [Stop]()
  48.         Running = False
  49.         MicroRunning.WaitOne()
  50.     End Sub
  51.  
  52.     Public Shared Function Interval() As Decimal
  53.         Return TicksPerInterval
  54.     End Function
  55.     Public Shared Function Interval(ByVal NewIntervalTicks As ULong) As Decimal
  56.         Dim CrntInterval As Decimal = TicksPerInterval
  57.         TicksPerInterval = NewIntervalTicks
  58.         Return CrntInterval
  59.     End Function
  60.     Public Shared Function Interval(ByVal NewIntervalTicks As Decimal) As Decimal
  61.         Dim CrntInterval As Decimal = TicksPerInterval
  62.         TicksPerInterval = NewIntervalTicks
  63.         Return CrntInterval
  64.     End Function
  65.     Public Shared Function Interval(ByVal NewIntervalMilliseconds As UInteger) As Decimal
  66.         Dim CrntInterval As Decimal = TicksPerInterval
  67.         TicksPerInterval = NewIntervalMilliseconds * TicksPerMillisecond
  68.         Return CrntInterval
  69.     End Function
  70.     Public Shared Function Interval(ByVal NewIntervalMilliseconds As Double) As Decimal
  71.         Dim CrntInterval As Decimal = TicksPerInterval
  72.         TicksPerInterval = NewIntervalMilliseconds * TicksPerMillisecond
  73.         Return CrntInterval
  74.     End Function
  75.  
  76.     <DllImport("winmm.dll")>
  77.     Private Shared Function timeBeginPeriod(ByVal msec As UInteger) As MMRESULT : End Function
  78.     <DllImport("winmm.dll")>
  79.     Private Shared Function timeEndPeriod(ByVal msec As UInteger) As MMRESULT : End Function
  80.     <DllImport("winmm.dll")>
  81.     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
  82.     End Function
  83.     <DllImport("winmm.dll")>
  84.     Private Shared Function timeKillEvent(ByVal id As UInteger) As MMRESULT : End Function
  85.     Private Delegate Sub TimerEventDel(ByVal id As UInteger, ByVal msg As UInteger, ByVal user As IntPtr, ByVal dw1 As IntPtr, ByVal dw2 As IntPtr)
  86.     Private Enum MMRESULT
  87.         MMSYSERR_NOERROR = 0
  88.         MMSYSERR_ERROR = 1
  89.         MMSYSERR_BADDEVICEID = 2
  90.         MMSYSERR_NOTENABLED = 3
  91.         MMSYSERR_ALLOCATED = 4
  92.         MMSYSERR_INVALHANDLE = 5
  93.         MMSYSERR_NODRIVER = 6
  94.         MMSYSERR_NOMEM = 7
  95.         MMSYSERR_NOTSUPPORTED = 8
  96.         MMSYSERR_BADERRNUM = 9
  97.         MMSYSERR_INVALFLAG = 10
  98.         MMSYSERR_INVALPARAM = 11
  99.         MMSYSERR_HANDLEBUSY = 12
  100.         MMSYSERR_INVALIDALIAS = 13
  101.         MMSYSERR_BADDB = 14
  102.         MMSYSERR_KEYNOTFOUND = 15
  103.         MMSYSERR_READERROR = 16
  104.         MMSYSERR_WRITEERROR = 17
  105.         MMSYSERR_DELETEERROR = 18
  106.         MMSYSERR_VALNOTFOUND = 19
  107.         MMSYSERR_NODRIVERCB = 20
  108.         WAVERR_BADFORMAT = 32
  109.         WAVERR_STILLPLAYING = 33
  110.         WAVERR_UNPREPARED = 34
  111.     End Enum
  112. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement