• 正文
  • 推薦器件
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

C#如何實(shí)現(xiàn)納秒級(jí)的計(jì)時(shí)器功能

2024/02/21
4599
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

在 C#開發(fā)過程中,經(jīng)常需要用到定時(shí)器,如果只是為了開啟一個(gè)線程,或者異步的做一些事情倒還好,直接使用 Form 或者 Thread 的 Timer 功能即可。

但是如果需求是比較精確的計(jì)時(shí)功能,這個(gè) Timer 就極不好用了,因?yàn)樗麄兪蔷€程上的定時(shí)器,會(huì)受到系統(tǒng)調(diào)度的干擾,精度非常差,CPU 使用率高一點(diǎn)點(diǎn)就會(huì)影響計(jì)時(shí)精度。

常用的 Windows API 方法 GetTickCount() 返回系統(tǒng)啟動(dòng)后經(jīng)過的毫秒數(shù)。另一方面,GetTickCount() 函數(shù)僅有 1ms 的分辨精度,精度也很不好。

我們要另外尋找一種方法來精確測量時(shí)間。

Win32 API 使用 QueryPerformanceCounter() 和 QueryPerformanceFrequency() 方法支持高精度計(jì)時(shí)。這些方法,比“標(biāo)準(zhǔn)的”毫秒精度的計(jì)時(shí)方法如 GetTickCount() 之類有高得多的精度。

雖然在 C# 中使用“非托管”的 API 函數(shù)會(huì)有一定的開銷,但比起使用一點(diǎn)都不精確的 GetTickCount() API 函數(shù)來說要好得多了。

下面的類實(shí)現(xiàn)了 QueryPerformanceCounter() 和 QueryPerformanceFrequency() API 函數(shù)功能的封裝

using System;using System.Runtime.InteropServices;using System.ComponentModel;using System.Threading;
namespace Win32{    internal class HighTimer    {        [DllImport("Kernel32.dll")]        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
        [DllImport("Kernel32.dll")]        private static extern bool QueryPerformanceFrequency(out long lpFrequency);
        private long startTime, stopTime;        private long freq;
        // 構(gòu)造函數(shù)        public HighTimer()        {            startTime = 0;            stopTime = 0;
            if (QueryPerformanceFrequency(out freq) == false)            {                // 不支持高性能計(jì)數(shù)器                throw new Win32Exception();            }        }
        // 開始計(jì)時(shí)器        public void Start()        {            // 來讓等待線程工作            Thread.Sleep(0);            QueryPerformanceCounter(out startTime);        }
        // 停止計(jì)時(shí)器        public void Stop()        {            QueryPerformanceCounter(out stopTime);        }
        // 返回計(jì)時(shí)器經(jīng)過時(shí)間(單位:秒)        public double Duration        {            get            {                return (double)(stopTime - startTime) / (double)freq;            }        }    }}

上面封裝類的使用方法:

HighTimer pt = new HighTimer();    // 創(chuàng)建新的 HighTimer 對象pt.Start();                         // 啟動(dòng)計(jì)時(shí)器Console.WriteLine("Test/n");        // 需要計(jì)時(shí)的代碼pt.Stop();                          // 停止計(jì)時(shí)器Console.WriteLine("Duration: {0} sec/n", pt.Duration); // 打印需要計(jì)時(shí)部分代碼的用時(shí)

 

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
CY62167EV30LL-45ZXI 1 Cypress Semiconductor Standard SRAM, 1MX16, 45ns, CMOS, PDSO48, TSOP1-48
$69.33 查看
M74VHC1GT126DF1G 1 onsemi Single Non-Inverting Buffer, TTL Level, SC-88A (SC-70-5 / SOT-353), 3000-REEL

ECAD模型

下載ECAD模型
$0.12 查看
KSZ8864CNXIA 1 Microchip Technology Inc DATACOM, ETHERNET TRANSCEIVER, QCC64

ECAD模型

下載ECAD模型
$7.74 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

多年硬件從業(yè)經(jīng)驗(yàn),專注分享從研發(fā)到供應(yīng)鏈,再到精益制造過程中的經(jīng)驗(yàn)和感悟!