原文:http://www.it118.org/specials/321869dd-98cb-431b-b6d2-82d973cd739d/d940a15c-0d36-4369-8de0-b07cf3f3fd5f.htmweb
前言:.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的計時器是您很是好的選擇。this
.NET 2.0前運行庫中不存在高精度的計時器,而您又須要它,解決的方法是經過調用QueryPerformanceFrequency 和 QueryPerformanceCounter這兩個Win32 API來實現。spa
- using System;
- using System.Runtime.InteropServices;
-
- internal sealed class AccurateTimerHelper
- {
- public AccurateTimerHelper()
- {
- TicksPerSecond = this.GetTicksPerSecond();
- this.BaseTime = this.GetTime();
- }
-
- [DllImport("kernel32.dll", EntryPoint="QueryPerformanceCounter")]
- private static extern int QueryPerformanceCounter(ref long lpPerformanceCount);
- [DllImport("kernel32.dll", EntryPoint="QueryPerformanceFrequency")]
- private static extern int QueryPerformanceFrequency(ref long A_0);
-
-
- public long GetElapsedTime()
- {
- return (long)((((double)(this.GetTime() - this.BaseTime)) / ((double)TicksPerSecond)) * 10000);
- }
-
- private long GetTime()
- {
- long time = 0;
- if (AccurateTimerHelper.QueryPerformanceCounter(ref time) == 0)
- {
- throw new NotSupportedException("Error while querying the high-resolution performance counter.");
- }
- return time;
- }
-
- private long GetTicksPerSecond()
- {
- long ticksPerSecond = 0;
- if (AccurateTimerHelper.QueryPerformanceFrequency(ref ticksPerSecond) == 0)
- {
- throw new NotSupportedException("Error while querying the performance counter frequency.");
- }
- return ticksPerSecond;
- }
-
-
- private long BaseTime
- {
- get
- {
- return baseTime;
- }
- set
- {
- this.baseTime = value;
- }
- }
-
- private long TicksPerSecond
- {
- get
- {
- return this.ticksPerSecond;
- }
- set
- {
- ticksPerSecond = value;
- }
- }
-
- private long baseTime;
- private long ticksPerSecond;
- }
調用很簡單: pwa
- AccurateTimerHelper atHelper = new AccurateTimerHelper();
-
-
-
- atHelper.GetElapsedTime()