| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- using System;
- namespace SKMC.Api.Common.Datetime
- {
- /// <summary>
- /// MicroStopwatch class
- /// </summary>
- public class MicroStopwatch : System.Diagnostics.Stopwatch
- {
- readonly double _microSecPerTick =
- 1000000D / System.Diagnostics.Stopwatch.Frequency;
- public MicroStopwatch()
- {
- if (!System.Diagnostics.Stopwatch.IsHighResolution)
- {
- throw new Exception("On this system the high-resolution " +
- "performance counter is not available");
- }
- }
- public long ElapsedMicroseconds
- {
- get
- {
- return (long)(ElapsedTicks * _microSecPerTick);
- }
- }
- }
- /// <summary>
- /// MicroTimer class
- /// </summary>
- public class MicroTimer
- {
- public delegate void MicroTimerElapsedEventHandler(
- object sender,
- MicroTimerEventArgs timerEventArgs);
- public event MicroTimerElapsedEventHandler MicroTimerElapsed;
- System.Threading.Thread _threadTimer = null;
- long _ignoreEventIfLateBy = long.MaxValue;
- long _timerIntervalInMicroSec = 0;
- bool _stopTimer = true;
- public MicroTimer()
- {
- }
- public MicroTimer(long timerIntervalInMicroseconds)
- {
- Interval = timerIntervalInMicroseconds;
- }
- public long Interval
- {
- get
- {
- return System.Threading.Interlocked.Read(
- ref _timerIntervalInMicroSec);
- }
- set
- {
- System.Threading.Interlocked.Exchange(
- ref _timerIntervalInMicroSec, value);
- }
- }
- public long IgnoreEventIfLateBy
- {
- get
- {
- return System.Threading.Interlocked.Read(
- ref _ignoreEventIfLateBy);
- }
- set
- {
- System.Threading.Interlocked.Exchange(
- ref _ignoreEventIfLateBy, value <= 0 ? long.MaxValue : value);
- }
- }
- public bool Enabled
- {
- set
- {
- if (value)
- {
- Start();
- }
- else
- {
- Stop();
- }
- }
- get
- {
- return (_threadTimer != null && _threadTimer.IsAlive);
- }
- }
- public void Start()
- {
- if (Enabled || Interval <= 0)
- {
- return;
- }
- _stopTimer = false;
- System.Threading.ThreadStart threadStart = delegate()
- {
- NotificationTimer(ref _timerIntervalInMicroSec,
- ref _ignoreEventIfLateBy,
- ref _stopTimer);
- };
- _threadTimer = new System.Threading.Thread(threadStart);
- _threadTimer.Priority = System.Threading.ThreadPriority.Highest;
- _threadTimer.Start();
- }
- public void Stop()
- {
- _stopTimer = true;
- }
- public void StopAndWait()
- {
- StopAndWait(System.Threading.Timeout.Infinite);
- }
- public bool StopAndWait(int timeoutInMilliSec)
- {
- _stopTimer = true;
- if (!Enabled || _threadTimer.ManagedThreadId ==
- System.Threading.Thread.CurrentThread.ManagedThreadId)
- {
- return true;
- }
- return _threadTimer.Join(timeoutInMilliSec);
- }
- public void Abort()
- {
- _stopTimer = true;
- if (Enabled)
- {
- _threadTimer.Abort();
- }
- }
- void NotificationTimer(ref long timerIntervalInMicroSec,
- ref long ignoreEventIfLateBy,
- ref bool stopTimer)
- {
- int timerCount = 0;
- long nextNotification = 0;
- MicroStopwatch microStopwatch = new MicroStopwatch();
- microStopwatch.Start();
- while (!stopTimer)
- {
- long callbackFunctionExecutionTime =
- microStopwatch.ElapsedMicroseconds - nextNotification;
- long timerIntervalInMicroSecCurrent =
- System.Threading.Interlocked.Read(ref timerIntervalInMicroSec);
- long ignoreEventIfLateByCurrent =
- System.Threading.Interlocked.Read(ref ignoreEventIfLateBy);
- nextNotification += timerIntervalInMicroSecCurrent;
- timerCount++;
- long elapsedMicroseconds = 0;
- while ( (elapsedMicroseconds = microStopwatch.ElapsedMicroseconds)
- < nextNotification)
- {
- System.Threading.Thread.SpinWait(10);
- }
- long timerLateBy = elapsedMicroseconds - nextNotification;
- if (timerLateBy >= ignoreEventIfLateByCurrent)
- {
- continue;
- }
- MicroTimerEventArgs microTimerEventArgs =
- new MicroTimerEventArgs(timerCount,
- elapsedMicroseconds,
- timerLateBy,
- callbackFunctionExecutionTime);
- MicroTimerElapsed(this, microTimerEventArgs);
- }
- microStopwatch.Stop();
- }
- }
- /// <summary>
- /// MicroTimer Event Argument class
- /// </summary>
- public class MicroTimerEventArgs : EventArgs
- {
- // Simple counter, number times timed event (callback function) executed
- public int TimerCount { get; private set; }
- // Time when timed event was called since timer started
- public long ElapsedMicroseconds { get; private set; }
- // How late the timer was compared to when it should have been called
- public long TimerLateBy { get; private set; }
- // Time it took to execute previous call to callback function (OnTimedEvent)
- public long CallbackFunctionExecutionTime { get; private set; }
- public MicroTimerEventArgs(int timerCount,
- long elapsedMicroseconds,
- long timerLateBy,
- long callbackFunctionExecutionTime)
- {
- TimerCount = timerCount;
- ElapsedMicroseconds = elapsedMicroseconds;
- TimerLateBy = timerLateBy;
- CallbackFunctionExecutionTime = callbackFunctionExecutionTime;
- }
- }
- }
|