C#精确计时
2013-12-26 13:15
525 查看
精确计时主要有以下几种方式
缺点:返回值是uint,最大值是2的32次方,因此如果服务器连续开机大约49天以后,该方法取得的返回值会归零
用法:?
一般默认的精度不止1毫秒(不同操作系统有所不同),需要调用timeBeginPeriod与timeEndPeriod来设置精度
用法:?
用法:?
注:经过测试,发现GetTickCount、System.Environment.TickCount也可以用timeBeginPeriod与timeEndPeriod来设置精度,最高可将精度提高到1毫秒。不知是什么原因?
用法:?
精度为百万分之一秒。而且由于是long型,所以不存在上面几个API位数不够的问题。
缺点:在一篇文章看到,该API在节能模式的时候结果偏慢,超频模式的时候又偏快,而且用电池和接电源的时候效果还不一样(笔记本)原文地址:http://delphi.xcjc.net/viewthread.php?tid=1570未经过超频等测试,如果是真的,那该API出来的结果就可能不准。
实际上它里面就是将QueryPerformanceCounter、QueryPerformanceFrequency两个WIN API封装了一下,如果硬件支持高精度,就调用QueryPerformanceCounter,如果不支持就用DateTime.Ticks来计算。
用法:?
1 调用WIN API中的GetTickCount
[DllImport("kernel32")] static extern uint GetTickCount();从操作系统启动到现在所经过的毫秒数,精度为1毫秒,经简单测试发现其实误差在大约在15ms左右
缺点:返回值是uint,最大值是2的32次方,因此如果服务器连续开机大约49天以后,该方法取得的返回值会归零
用法:?
123 | uint s1 = GetTickCount(); Thread.Sleep(2719); Console.WriteLine(GetTickCount() - s1); //单位毫秒 |
2 调用WIN API中的timeGetTime 推荐
[DllImport("winmm")] static extern uint timeGetTime();常用于多媒体定时器中,与GetTickCount类似,也是返回操作系统启动到现在所经过的毫秒数,精度为1毫秒。
一般默认的精度不止1毫秒(不同操作系统有所不同),需要调用timeBeginPeriod与timeEndPeriod来设置精度
[DllImport("winmm")] static extern void timeBeginPeriod(int t); [DllImport("winmm")] static extern void timeEndPeriod(int t);缺点:与GetTickCount一样,受返回值的最大位数限制。
用法:?
12345 | timeBeginPeriod(1); uint start = timeGetTime(); Thread.Sleep(2719); Console.WriteLine(timeGetTime() - start); //单位毫秒 timeEndPeriod(1); |
3 调用.net自带的方法System.Environment.TickCount
获取系统启动后经过的毫秒数。经反编译猜测它可能也是调用的GetTickCount,但是它的返回值是int,而GetTickCount与timeGetTime方法的原型中返回值是DWORD,对应C#中的uint,难道.NET对System.Environment.TickCount另外还做了什么处理么?缺点:与GetTickCount一样,受返回值的最大位数限制。用法:?
123 | int aa = System.Environment.TickCount; Thread.Sleep(2719); Console.WriteLine(System.Environment.TickCount - aa); //单位毫秒 |
4 调用WIN API中的QueryPerformanceCounter
[DllImport("kernel32.dll ")] static extern bool QueryPerformanceCounter(ref long lpPerformanceCount);用于得到高精度计时器(如果存在这样的计时器)的值。微软对这个API解释就是每秒钟某个计数器增长的数值。如果安装的硬件不支持高精度计时器,函数将返回false需要配合另一个API函数QueryPerformanceFrequency。
[DllImport("kernel32")] static extern bool QueryPerformanceFrequency(ref long PerformanceFrequency);QueryPerformanceFrequency返回硬件支持的高精度计数器的频率,如果安装的硬件不支持高精度计时器,函数将返回false。
用法:?
1234567 | long a = 0; QueryPerformanceFrequency( ref a); long b = 0, c = 0; QueryPerformanceCounter( ref b); Thread.Sleep(2719); QueryPerformanceCounter( ref c); Console.WriteLine((c - b) / ( decimal )a); //单位秒 |
缺点:在一篇文章看到,该API在节能模式的时候结果偏慢,超频模式的时候又偏快,而且用电池和接电源的时候效果还不一样(笔记本)原文地址:http://delphi.xcjc.net/viewthread.php?tid=1570未经过超频等测试,如果是真的,那该API出来的结果就可能不准。
5 使用.net的System.Diagnostics.Stopwatch类 推荐
Stopwatch 在基础计时器机制中对计时器的刻度进行计数,从而测量运行时间。如果安装的硬件和操作系统支持高分辨率性能的计数器,则 Stopwatch 类将使用该计数器来测量运行时间;否则,Stopwatch 类将使用系统计数器来测量运行时间。使用 Frequency 和 IsHighResolution 两个静态字段可以确定实现 Stopwatch 计时的精度和分辨率。实际上它里面就是将QueryPerformanceCounter、QueryPerformanceFrequency两个WIN API封装了一下,如果硬件支持高精度,就调用QueryPerformanceCounter,如果不支持就用DateTime.Ticks来计算。
用法:?
12345 | Stopwatch sw = new Stopwatch(); sw.Start(); Thread.Sleep(2719); sw.Stop(); Console.WriteLine(sw.ElapsedTicks / ( decimal )Stopwatch.Frequency); C#高精度计时简介精确的时间计量方法在某些应用程序中是非常重要的。常用的 Windows API 方法GetTickCount() 返回系统启动后经过的毫秒数。另一方面,GetTickCount() 函数仅有 1ms 的分辨精度,很不精确。故而,我们要另外寻找一种方法来精确测量时间。Win32 API 使用 QueryPerformanceCounter() 和 QueryPerformanceFrequency() 方法支持高精度计时。这些方法,比“标准的”毫秒精度的计时方法如 GetTickCount() 之类有高得多的精度。另一方面来说,在 C# 中使用“非托管”的 API 函数会有一定的开销,但比起使用一点都不精确的 GetTickCount() API 函数来说要好得多了。第一个函数 QueryPerformanceCounter() 查询任意时刻高精度计数器的实际值。第二个函数 QueryPerformanceFrequency() 返回高精度计数器每秒的计数值。为了获得某一代码段经历的时间,你需要获得代码段开始前和结束后这两个计时时刻的高精度计数器实际值。这两个值的差指出了代码段执行所经历的时间。然后通过将差除以每秒计数值(高精度计时器频率),就可以计算经过的时间了。duration = (stop - start) / frequency经过时间 = (停止时间 - 开始时间) / 频率需要关于 QueryPerformanceCounter 和 QueryPerformanceFrequency 的更多信息,请参阅 MSDN 文档。代码下面的类实现了 QueryPerformanceCounter() 和 QueryPerformanceFrequency() API 函数的功能。
Start() 开始计时,Stop() 停止计时。要获得经过的时间,调用 Duration() 函数即可。参考下面的例子。
高精度计时 private void button1_Click_1(object sender, EventArgs e) { System.Diagnostics.Stopwatch MyWatch =new System.Diagnostics.Stopwatch(); MyWatch.Start(); System.Threading.Thread.Sleep(100); MyWatch.Stop(); MessageBox.Show( MyWatch.ElapsedMilliseconds.ToString() + "毫秒"); }////当计算时间进入纳秒级时,Stopwatch(最小精是毫秒) 是无法计时的,还Environment.TickCount获取系统启动应用程序的毫秒级。对于要求不高,计算时间在毫秒级可以用Stopwatc或Environment.TickCount。若有计算纳秒级的计时就只能使用上面第一种方法。 |
相关文章推荐
- C#中精确计时的一点收获
- C#中精确计时的一点收获
- C#中精确计时的一点收获
- C#中精确计时的一点收获
- 计时精度到底毫秒级别或者更高 如何使用C#制作一个精确计时器
- C#中精确计时的一点收获
- C#中精确计时的一点收获!!!
- C#中精确计时的一点收获
- 关于C#中精确计时的问题
- C#中精确计时的一点收获
- C#实现精确计时,精度1ms
- C#中精确计时的一点收获
- C# 时间(几个常用时间,程序运行计时,页面运行计时)
- 自定义打印纸张 c# gdi+ 精确位置打印 套打
- C#实现精确查询和模糊查询
- Linux_arm驱动之按键模拟脉冲实现定时器的精确计时 (实例)
- C# DateTime 精确到秒/截断毫秒部分
- C# 时间函数(几个常用时间,程序运行计时,页面运行计时)
- 自定义打印纸张 c# gdi+ 精确位置打印 套打
- C/C++中如何精确计时