C#下利用高精度计时器进行计时操作

Posted James

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#下利用高精度计时器进行计时操作相关的知识,希望对你有一定的参考价值。

简介

精确的时间计量方法在某些应用程序中是非常重要的。常用的 Windows API 方法 GetTickCount() 返回系统启动后经过的毫秒数。另一方面,GetTickCount() 函数仅有 1ms 的分辨精度,很不精确。

故而,我们要另外寻找一种方法来精确测量时间。

Win32 API 使用 QueryPerformanceCounter() 和 QueryPerformanceFrequency() 方法支持高精度计时。这些方法,比“标准的”毫秒精度的计时方法如 GetTickCount() 之类有高得多的精度。另一方面来说,在 C# 中使用“非托管”的 API 函数会有一定的开销,但比起使用一点都不精确的 GetTickCount() API 函数来说要好得多了。

第一个函数 QueryPerformanceCounter() 查询任意时刻高精度计数器的实际值。第二个函数 QueryPerformanceFrequency() 返回高精度计数器每秒的计数值。为了获得某一代码段经历的时间,你需要获得代码段开始前和结束后这两个计时时刻的高精度计数器实际值。这两个值的差指出了代码段执行所经历的时间。

然后通过将差除以每秒计数值(高精度计时器频率),就可以计算经过的时间了。

duration = (stop - start) / frequency
经过时间 = (停止时间 - 开始时间) / 频率

下面的类实现了 QueryPerformanceCounter() 和 QueryPerformanceFrequency() API 函数的功能。

  1. public class HiperTimer

  2. [DllImport("Kernel32.dll")]
  3. private static extern bool QueryPerformanceCounter(out long lpPerformanceCount); //查询高精度计数器该时刻的实际值
  4. [DllImport("Kernel32.dll")]
  5. private static extern bool QueryPerformanceFrequency(out long lpFrequency); //查询高精度计数器每秒的计数次数
  6.  
  7. private long _startTime, _stopTime;
  8. private readonly long _frequency;
  9.  
  10. // 构造函数
  11. public HiperTimer()

  12. _startTime = 0;
  13. _stopTime = 0;
  14.  
  15. if (QueryPerformanceFrequency(out _frequency) == false)
  16. // 不支持高性能计数器
  17. throw new Win32Exception();

  18.  
  19. // 开始计时器
  20. public void Start()

  21. // 来让等待线程工作
  22. Thread.Sleep(0);
  23. QueryPerformanceCounter(out _startTime);
  24.  
  25. // 停止计时器
  26. public void Stop()

  27. QueryPerformanceCounter(out _stopTime);
  28.  
  29. // 返回计时器经过时间(单位:秒)
  30. public double EliminatedSecond

  31. get

  32. return (_stopTime - _startTime) / (double) _frequency;

  33.  
  34. public double EliminatedMilliSecond

  35. get return (double) (_stopTime - _startTime)*1000/_frequency;
  36.  
  37. public double EliminatedMicroSecond

  38. get return (double)(_stopTime - _startTime) * 1000000 / _frequency;
  39.  

使用过程如下:

  1. private static void Main(string[] args)

  2. var pt = new HiperTimer();
  3.  
  4. pt.Start(); // 启动计时器
  5. Console.WriteLine("Test the time.\\n"); // 需要计时的代码
  6. pt.Stop(); // 停止计时器
  7.  
  8. Console.WriteLine("Duration: 0 sec",pt.EliminatedSecond);
  9. Console.WriteLine("Duration: 0 ms", pt.EliminatedMilliSecond);
  10. Console.WriteLine("Duration: 0 us", pt.EliminatedMicroSecond);

运行结果:

 

来源:https://www.shuzhiduo.com/A/QW5YXnZ3Jm/

以上是关于C#下利用高精度计时器进行计时操作的主要内容,如果未能解决你的问题,请参考以下文章

C#中定时器执行定时器触发任务是单线程还是多线程?

c#的timer控件计时不够准确,有啥办法可以替代吗,我需要10ms左右的精度,但是timer很不准确

如何在VB中做精确度高的计时器??

如何以亚秒级精度计时操作的持续时间?

当 CPU 利用率和内存增加时,计时器间隔增加

c#计时器用法