DeviceTimer.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6. namespace Aitex.Core.Util
  7. {
  8. /// <summary>
  9. /// DeviceTimer类
  10. ///
  11. /// 设计目的:
  12. /// 1. 进行ms级别的定时;
  13. /// 2. 弥补使用Windows系统时间作为定时,如果系统时间被更改,定时器面临误判风险(Alpha机台已有多次发生类似事件);
  14. ///
  15. /// 使用场合:
  16. /// 系统中凡是需要定时完成的事件,建议采用该定时器完成定时功能;
  17. /// </summary>
  18. public class DeviceTimer
  19. {
  20. //引入高性能计数器API,通过对CPU计数完成计时
  21. [DllImport("Kernel32.dll")]
  22. private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
  23. //获取当前CPU的工作频率
  24. [DllImport("Kernel32.dll")]
  25. private static extern bool QueryPerformanceFrequency(out long lpFrequency);
  26. /// <summary>
  27. /// 定时器内部状态定义
  28. /// </summary>
  29. private enum DeviceTimerState
  30. {
  31. TM_ST_IDLE = 0,
  32. TM_ST_BUSY = 1,
  33. TM_ST_TIMEOUT = 2,
  34. }
  35. /// <summary>
  36. /// 定时器内部状态
  37. /// </summary>
  38. DeviceTimerState _state;
  39. /// <summary>
  40. /// 定时器开始计时时刻的相对时间点
  41. /// </summary>
  42. long _startTime;
  43. /// <summary>
  44. /// 定时器超时时刻的相对时间点
  45. /// </summary>
  46. long _timeOut;
  47. /// <summary>
  48. /// CPU运行的时钟频率
  49. /// </summary>
  50. double _freq;
  51. /// <summary>
  52. /// 定时时间(单位:ms)
  53. /// </summary>
  54. double _duration;
  55. /// <summary>
  56. /// class constructure
  57. /// </summary>
  58. public DeviceTimer()
  59. {
  60. long freq;
  61. if (QueryPerformanceFrequency(out freq) == false)
  62. throw new Exception("本计算机不支持高性能计数器");
  63. //得到每1ms的CPU计时TickCount数目
  64. _freq = (double)freq / 1000.0;
  65. SetState(DeviceTimerState.TM_ST_IDLE);
  66. QueryPerformanceCounter(out _startTime);
  67. _timeOut = _startTime;
  68. _duration = 0;
  69. }
  70. /// <summary>
  71. /// 内部调用:设置定时器当前状态
  72. /// </summary>
  73. /// <param name="state"></param>
  74. private void SetState(DeviceTimerState state)
  75. {
  76. _state = state;
  77. }
  78. /// <summary>
  79. /// 内部调用:返回定时器当前状态
  80. /// </summary>
  81. /// <returns></returns>
  82. private DeviceTimerState GetState()
  83. {
  84. return _state;
  85. }
  86. /// <summary>
  87. /// 定时器开始计时到现在已流逝的时间(单位:毫秒)
  88. /// </summary>
  89. /// <returns></returns>
  90. public double GetElapseTime()
  91. {
  92. long curCount;
  93. QueryPerformanceCounter(out curCount);
  94. return (double)(curCount - _startTime) / (double)_freq;
  95. }
  96. /// <summary>
  97. /// 获取定时总时间
  98. /// </summary>
  99. /// <returns></returns>
  100. public double GetTotalTime()
  101. {
  102. return _duration;
  103. }
  104. /// <summary>
  105. /// 停止计时器计时
  106. /// </summary>
  107. public void Stop()
  108. {
  109. SetState(DeviceTimerState.TM_ST_IDLE);
  110. QueryPerformanceCounter(out _startTime);
  111. _timeOut = _startTime;
  112. _duration = 0;
  113. }
  114. /// <summary>
  115. /// 启动定时器
  116. /// </summary>
  117. /// <param name="delay_ms">定时时间(单位:毫秒)</param>
  118. public void Start(double delay_ms)
  119. {
  120. QueryPerformanceCounter(out _startTime);
  121. _timeOut = Convert.ToInt64(_startTime + delay_ms * _freq);
  122. SetState(DeviceTimerState.TM_ST_BUSY);
  123. _duration = delay_ms;
  124. }
  125. /// <summary>
  126. /// 重新开始定时器
  127. /// 开始的计时时间以上一次Start的时间为准
  128. /// </summary>
  129. /// <param name="delay_ms">定时时间(单位:毫秒)</param>
  130. public void Restart(double delay_ms)
  131. {
  132. _timeOut = Convert.ToInt64(_startTime + delay_ms * _freq);
  133. SetState(DeviceTimerState.TM_ST_BUSY);
  134. _duration = delay_ms;
  135. }
  136. /// <summary>
  137. /// 返回定时器是否超时
  138. /// </summary>
  139. /// <returns></returns>
  140. public bool IsTimeout()
  141. {
  142. if (_state == DeviceTimerState.TM_ST_IDLE)
  143. {
  144. //System.Diagnostics.Debug.WriteLine("Warning: Misuage of the device timer. You must start it first before you can use it.");
  145. //System.Diagnostics.Debug.Assert(false, "Warning: Misuage of the device timer. You must start it first before you can use it.");
  146. }
  147. long curCount;
  148. QueryPerformanceCounter(out curCount);
  149. if (_state == DeviceTimerState.TM_ST_BUSY && (curCount >= _timeOut))
  150. {
  151. SetState(DeviceTimerState.TM_ST_TIMEOUT);
  152. return true;
  153. }
  154. else if (_state == DeviceTimerState.TM_ST_TIMEOUT)
  155. {
  156. return true;
  157. }
  158. return false;
  159. }
  160. /// <summary>
  161. /// 定时器是否在工作中
  162. /// </summary>
  163. /// <returns></returns>
  164. public bool IsIdle()
  165. {
  166. return (_state == DeviceTimerState.TM_ST_IDLE);
  167. }
  168. }
  169. }