TizzyT

MicroTimer 2018 (commented) -TizzyT

Sep 1st, 2018
444
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4. using System.Threading;
  5.  
  6. public class MicroTimer : IDisposable
  7. {
  8.     // Windows Multi-Media library to request a higher resolution period for the timer.
  9.     [DllImport("winmm.dll")]
  10.     private static extern uint timeBeginPeriod(uint msec);
  11.        
  12.     // Computes how many ticks are in each millisecond.
  13.     private static readonly decimal TicksPerMillisecond = Stopwatch.Frequency / 1000M;
  14.     // Stores the next time the Timer should elapse at.
  15.     private decimal NextTime;
  16.     // The thread which to keep track of timing, as to not block.
  17.     private Thread Iterator;
  18.     // Stores the number of millisecond the next iteration will wait for.
  19.     private int Ms;
  20.  
  21.     // The Elapsed event, fired when the Timer has reached or exceeded its NextTIme value.
  22.     public event ElapsedEventHandler Elapsed;
  23.     public delegate void ElapsedEventHandler();
  24.     // The number of ticks each iteration will take.
  25.     public decimal Interval { get; set; }
  26.  
  27.     // Static constructor to request high resolution from Operation System. Throws if fails.
  28.     static MicroTimer()
  29.     {
  30.         if (timeBeginPeriod(1) != 0) throw new Exception("High resolution timer not available.");
  31.     }
  32.  
  33.     // Default constructor which initializes the interval to 1 second.
  34.     public MicroTimer() => Interval = TicksPerMillisecond;
  35.  
  36.     // Starts the Timer if it hasn't started already.
  37.     public void Start(bool initial = false)
  38.     {
  39.         if (Iterator == null)
  40.         {
  41.             // Sets the NextTime to the current time with the addition of the Interval (ticks per iteration) if specified.
  42.             NextTime = Stopwatch.GetTimestamp() + (initial ? 0 : Interval);
  43.             // Initializes a new thread
  44.             Iterator = new Thread(() =>
  45.             {
  46.                 // Infinite loop to track time.
  47.                 while (true)
  48.                 {
  49.                     // Assigns Ms to how much time in millisecond until NextTime is reached and if that evaluation is greater than 0. If it is, sleep for that amount in milliseconds.
  50.                     if ((Ms = (int)(Math.Floor((NextTime - Stopwatch.GetTimestamp()) / TicksPerMillisecond))) > 0) Thread.Sleep(Ms);
  51.                     // Poll with the remaining left over Ticks (sub millisecond precision).
  52.                     while (Stopwatch.GetTimestamp() < NextTime) ;
  53.                     // Fire Elapsed Event if not null.
  54.                     Elapsed?.Invoke();
  55.                     // Set the NextTime to the next iteration.
  56.                     NextTime += Interval;
  57.                 }
  58.             })
  59.             {
  60.                 Priority = ThreadPriority.Highest, // Have this thread at a high priority.
  61.                 IsBackground = true // Prevent thread from still running after application has closed.
  62.             };
  63.             Iterator.Start(); // Starts the Thread.
  64.         }
  65.     }
  66.  
  67.     // Stops the Thread and nulls it.
  68.     public void Stop()
  69.     {
  70.         if (Iterator != null)
  71.         {
  72.             Iterator.Abort();
  73.             Iterator = null;
  74.         }
  75.     }
  76.  
  77.     // Disposes this object (implemented to the using statement can be used).
  78.     public void Dispose() => Iterator?.Abort();
  79. }
Add Comment
Please, Sign In to add comment