根据综合网上的一些文章,精确计时主要有以下几种方式
1 调用WIN API中的GetTickCount
[ DllImport( "kernel32") ] staticexternuintGetTickCount( ) ;
从操作系统启动到现在所经过的毫秒数,精度为1毫秒,经简单测试发现其实误差在大约在15ms左右
缺点:返回值是uint,最大值是2的32次方,因此如果服务器连续开机大约49天以后,该方法取得的返回值会归零
用法:
uints1 = GetTickCount;
Thread.Sleep( 2719);
Console.WriteLine(GetTickCount - s1); //单位毫秒
2 调用WIN API中的timeGetTime 推荐
[ DllImport( "winmm") ]
staticexternuinttimeGetTime( ) ;
常用于多媒体定时器中,与GetTickCount类似,也是返回操作系统启动到现在所经过的毫秒数,精度为1毫秒。
一般默认的精度不止1毫秒(不同操作系统有所不同),需要调用timeBeginPeriod与timeEndPeriod来设置精度
[ DllImport( "winmm") ]
staticexternvoidtimeBeginPeriod( intt ) ;
[ DllImport( "winmm") ]
staticexternvoidtimeEndPeriod( intt ) ;
缺点:与GetTickCount一样,受返回值的最大位数限制。
用法:
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一样,受返回值的最大位数限制。
用法:
intaa = System.Environment.TickCount;
Thread.Sleep( 2719);
Console.WriteLine(System.Environment.TickCount - aa); //单位毫秒
注:经过测试,发现GetTickCount、System.Environment.TickCount也可以用timeBeginPeriod与timeEndPeriod来设置精度,最高可将精度提高到1毫秒。不知是什么原因?
4 调用WIN API中的QueryPerformanceCounter
[ DllImport( "kernel32.dll ") ]
staticexternboolQueryPerformanceCounter( reflonglpPerformanceCount ) ;
用于得到高精度计时器(如果存在这样的计时器)的值。微软对这个API解释就是每秒钟某个计数器增长的数值。
如果安装的硬件不支持高精度计时器,函数将返回false需要配合另一个API函数QueryPerformanceFrequency。
[ DllImport( "kernel32") ]
staticexternboolQueryPerformanceFrequency( reflongPerformanceFrequency ) ;
QueryPerformanceFrequency返回硬件支持的高精度计数器的频率,如果安装的硬件不支持高精度计时器,函数将返回false。
用法:
longa = 0; QueryPerformanceFrequency( refa); longb = 0, c = 0; QueryPerformanceCounter( refb); Thread.Sleep( 2719); QueryPerformanceCounter( refc); Console.WriteLine((c - b) / ( decimal)a); //单位秒
精度为百万分之一秒。而且由于是long型,所以不存在上面几个API位数不够的问题。
缺点:在一篇文章看到,该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来计算。
用法:
Stopwatch sw = newStopwatch; sw.Start;Thread.Sleep( 2719); sw.Stop;Console.WriteLine(sw.ElapsedTicks / ( decimal)Stopwatch.Frequency);
6 使用CPU时间戳进行更高精度计时
该方法的原理我不是很明白,硬件知识太匮乏了。精度是ns
在C#中要用该方法必须先建立一个托管C++项目(因为要内嵌汇编),编译成DLL供c#调用,有点麻烦。
C++代码:
// MLTimerDot.h# pragmaonce usingnamespaceSystem; namespaceMLTimerDot{ //得到计算机启动到现在的时钟周期unsigned __ int64 GetCycleCount( void) {_asm _emit 0x0F_asm _emit 0x31} //声明 .NET 类public__gc classMLTimer{ public: MLTimer( void) {} //计算时钟周期UInt64 GetCount( void) { returnGetCycleCount; }};}
C#调用:
longa = 0; QueryPerformanceFrequency( refa); MLTimerDot.MLTimer timer = newMLTimerDot.MLTimer; ulongss= timer.GetCount; Thread.Sleep( 2719); Console.WriteLine((timer.GetCount - ss) / ( decimal)a);
缺点:和QueryPerformanceCounter一样,结果不太稳定。
我的结论:常规应用下timeGetTime完全够用了,将精度调到1毫秒,大部分境况都够用。System.Diagnostics.Stopwatch由于调用方便,也推荐使用
来源公众号:dotNET编程大全
版权声明:本文来源于网友收集或网友供稿,仅供学习交流之用,如果有侵权,请转告小编或者留言,本公众号立即删除。
支持小薇
关注公众号 ↑ ↑ ↑: DotNet开发跳槽 ❀
点分享
点收藏
点点赞
点在看
2、本站永久网址:https://www.yuanmacun.com
3、本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
4、本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
6、本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
源码村资源网 » html5倒计时(倒计时 h5)
1 评论