原文:http://www.it118.org/specials/321869dd-98cb-431b-b6d2-82d973cd739d/d940a15c-0d36-4369-8de0-b07cf3f3fd5f.htm

前言:.NET 2.0前运行库中不存在高精度的计时器,而您又需要它,解决的方法是通过调用QueryPerformanceFrequency 和 QueryPerformanceCounter这两个Win32 API来实现。在.NET 2.0时,stopwatch类也可实现高精度计时,请参考:《使用Stopwatch类实现高精度计时

.NET运行库具有一个属性—— System.Environment.Tickcount,您可以使用它计算时间。该属性返回计算机最近一次启动之后,已用时间滴答数(ms)。一开始,您可能觉得它是一个非常好的工具。但是,它有一个相当显著的缺陷,即该属性并不是每毫秒都更新。

该属性的更新频率通常依赖于计时器的分辨率。在该案例中,tick-count属性的分辨率是15 ms。如果您在一个循环中持续访问该属性,则在更新之前的每15ms它返回相同的值,然后在下一次更新之前的另一个15ms中,它返回一个新的值。现代的计算机每秒能够执行非常巨大的计算量,15ms的分辨率将使得您的计算看上去好像“停停动动的”。

警告:

如果希望在应用程序中使用TickCount属性,那么必须明确它返回的是一个无符号整数值。因为该属性是计算机启动之后已用时间的滴答数,所以如果计算机运行了非常长的时间 (例如超过25天),该属性将返回一个负数。如果您没有考虑这种情况,将使得正在使用的公式出错。在更长的一段时间之后,该值将重新归0。

这里您需要的是一个具有更高分辨率的计时器。一个分辨率为1ms的计时器是您非常好的选择。

.NET 2.0前运行库中不存在高精度的计时器,而您又需要它,解决的方法是通过调用QueryPerformanceFrequency 和 QueryPerformanceCounter这两个Win32 API来实现。

  1. using System;
  2. using System.Runtime.InteropServices;
  3. internal sealed class AccurateTimerHelper
  4. {
  5. public AccurateTimerHelper()
  6. {
  7. TicksPerSecond = this.GetTicksPerSecond();
  8. this.BaseTime = this.GetTime();
  9. }
  10. [DllImport("kernel32.dll", EntryPoint="QueryPerformanceCounter")]
  11. private static extern int QueryPerformanceCounter(ref long lpPerformanceCount);
  12. [DllImport("kernel32.dll", EntryPoint="QueryPerformanceFrequency")]
  13. private static extern int QueryPerformanceFrequency(ref long A_0);
  14. public long GetElapsedTime()
  15. {
  16. return (long)((((double)(this.GetTime() - this.BaseTime)) / ((double)TicksPerSecond)) * 10000);
  17. }
  18. private long GetTime()
  19. {
  20. long time = 0;
  21. if (AccurateTimerHelper.QueryPerformanceCounter(ref time) == 0)
  22. {
  23. throw new NotSupportedException("Error while querying the high-resolution performance counter.");
  24. }
  25. return time;
  26. }
  27. private long GetTicksPerSecond()
  28. {
  29. long ticksPerSecond = 0;
  30. if (AccurateTimerHelper.QueryPerformanceFrequency(ref ticksPerSecond) == 0)
  31. {
  32. throw new NotSupportedException("Error while querying the performance counter frequency.");
  33. }
  34. return ticksPerSecond;
  35. }
  36. private long BaseTime
  37. {
  38. get
  39. {
  40. return baseTime;
  41. }
  42. set
  43. {
  44. this.baseTime = value;
  45. }
  46. }
  47. private long TicksPerSecond
  48. {
  49. get
  50. {
  51. return this.ticksPerSecond;
  52. }
  53. set
  54. {
  55. ticksPerSecond = value;
  56. }
  57. }
  58. private long baseTime;
  59. private long ticksPerSecond;
  60. }

调用很简单:

    1. AccurateTimerHelper atHelper = new AccurateTimerHelper();
    2. /*
    3. //进行很多费时操作
    4. */
    5. atHelper.GetElapsedTime()

.net平台下获取高精度时间类的更多相关文章

  1. Windows下获取高精度时间注意事项

    Windows下获取高精度时间注意事项 [转贴 AdamWu]   花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: ...

  2. 一个 C# 获取高精度时间类(调用API QueryP*)

    如果你觉得用 DotNet 自带的 DateTime 获取的时间精度不够,解决的方法是通过调用 QueryPerformanceFrequency 和 QueryPerformanceCounter这 ...

  3. Windows下获取高精度时间注意事项 [转贴 AdamWu]

    花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: A) 定义模糊 - 曾经据说是处理器的cycle counter, ...

  4. shell下获取系统时间

    shell下获取系统时间的方法直接调用系统变量 获取今天时期:`date +%Y%m%d` 或 `date +%F` 或 $(date +%y%m%d) 获取昨天时期:`date -d yesterd ...

  5. linux下获取系统时间 和 时间偏移

    获取linux时间  并计算时间偏移 void getSystemTimer(void){#if 0 char *wdate[]={"Sun","Mon",&q ...

  6. 获取高精度时间注意事项 (QueryPerformanceCounter , QueryPerformanceFrequency)

    花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: A) 定义模糊- 曾经据说是处理器的cycle counter,但 ...

  7. windows平台下获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号

    转自http://blog.csdn.net/jhqin/article/details/5548656,如有侵权,请联系本人删除,谢谢!! 头文件:WMI_DeviceQuery.h /* ---- ...

  8. windows和linux平台下的通用时间测试函数

    Time.cpp ////////////////////////////////////////////////////////////////////////////// // Timer.cpp ...

  9. VUE环境下获取当前时间并格式化--按秒数更新

    <el-col :span="8"><div class="grid-content title-time"> {{date}}< ...

随机推荐

  1. laravel 在windows中使用一键安装包步骤

    安装 PHP 注意一:Laravel 5.0 开始对 PHP 版本的要求是 >=5.4,Laravel 5.1 要求 PHP 版本 >=5.5.9,所以,建议大家尽量安装 5.5.x 的最 ...

  2. iOS推送遇到的问题

    1. 推送证书过期. 同事说iOS客户端不能推送消息,发现推送证书过期了,苹果的推送证书有效期是一年,推送证书过期后就不能使用推送服务了.解决办法:重新请求推送证书,导出p12文件,传给后台服务器就可 ...

  3. CS193P - 2016年秋 第三讲 Swift 语言及 Foundation 框架

    这一讲介绍一些 Swift 的重点概念.特别是一些有别于其它语言的地方.但本质上还都是语法糖. 想充分理解这一讲的内容,最好的方式就是 打开 playgound,亲自动手来实验. 1,Optional ...

  4. xtrabackup备份rds记录

    在执行最后一步时 mysqld_safe --defaults-file=/home/mysql/data/backup-my.cnf --user=mysql --datadir=/home/mys ...

  5. margin属性

    可以设置position:absolute/relative/fixed,通过调节top/bottom/left/right实现元素的定位,这样很好,但是有时候想通过margin来实现. 下面是mar ...

  6. Emmet使用之HTML

    前言 前段时间在网上发现一个强大的好玩的东西,emmet,它可以方便我们前端开发者快速编写html和css.可以算是前端开发必备的一款利器,今天先总结一下用emmet写html,有时间再总结下css的 ...

  7. WORD学习之制作座位表

    1.点击插入-表格-插入表格,将表格的列数设置为6,行数为10,再点击“确定”按钮

  8. NDK开发-Android Studio+gradle-experimental开发ndk

    在最新的Android Studio2.2的preview版中,增加全新的ndk支持,使用了新的gradle,以及DSL语言. 新的NDK需要使用新的Gradle插件和新的Android插件来支持! ...

  9. java三大框架

    1定义 集成SSH框架的系统从职责上分为四层:表示层.业务逻辑层.数据持久层和域模块层,以帮助开发人员在短期内搭建结构清晰.可复用性好.维护方便的Web应用程序.其中使用Struts作为系统的整体基础 ...

  10. Notepad++自动刷新文本

    现在的日志信息往往都是打印在硬盘上,而不是保存到线上,所以我们常常会使用notepad++来查看硬盘上的文本文件 这时往往会出现两个问题 (1)在notepad++长时间最小化后,再次打开会提示是否下 ...