加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

C#如何实现纳秒级的计时器功能

02/21 08:50
5118
阅读需 5 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

在 C#开发过程中,经常需要用到定时器,如果只是为了开启一个线程,或者异步的做一些事情倒还好,直接使用 Form 或者 Thread 的 Timer 功能即可。

但是如果需求是比较精确的计时功能,这个 Timer 就极不好用了,因为他们是线程上的定时器,会受到系统调度的干扰,精度非常差,CPU 使用率高一点点就会影响计时精度。

常用的 Windows API 方法 GetTickCount() 返回系统启动后经过的毫秒数。另一方面,GetTickCount() 函数仅有 1ms 的分辨精度,精度也很不好。

我们要另外寻找一种方法来精确测量时间。

Win32 API 使用 QueryPerformanceCounter() 和 QueryPerformanceFrequency() 方法支持高精度计时。这些方法,比“标准的”毫秒精度的计时方法如 GetTickCount() 之类有高得多的精度。

虽然在 C# 中使用“非托管”的 API 函数会有一定的开销,但比起使用一点都不精确的 GetTickCount() API 函数来说要好得多了。

下面的类实现了 QueryPerformanceCounter() 和 QueryPerformanceFrequency() API 函数功能的封装

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;
        // 构造函数        public HighTimer()        {            startTime = 0;            stopTime = 0;
            if (QueryPerformanceFrequency(out freq) == false)            {                // 不支持高性能计数器                throw new Win32Exception();            }        }
        // 开始计时器        public void Start()        {            // 来让等待线程工作            Thread.Sleep(0);            QueryPerformanceCounter(out startTime);        }
        // 停止计时器        public void Stop()        {            QueryPerformanceCounter(out stopTime);        }
        // 返回计时器经过时间(单位:秒)        public double Duration        {            get            {                return (double)(stopTime - startTime) / (double)freq;            }        }    }}

上面封装类的使用方法:

HighTimer pt = new HighTimer();    // 创建新的 HighTimer 对象pt.Start();                         // 启动计时器Console.WriteLine("Test/n");        // 需要计时的代码pt.Stop();                          // 停止计时器Console.WriteLine("Duration: {0} sec/n", pt.Duration); // 打印需要计时部分代码的用时

 

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
AT24CM01-SSHM-B 1 Atmel Corporation EEPROM, 128KX8, Serial, CMOS, PDSO8, 0.150 INCH, GREEN, PLASTIC, MS-012AA, SOIC-8
$1.85 查看
SFH551/1-1V 1 Avago Technologies FIBER OPTIC RECEIVER, 5Mbps, THROUGH HOLE MOUNT, PLASTIC PACKAGE-5
暂无数据 查看
KSZ8873MLLV 1 Microchip Technology Inc LAN Switching Circuit, PQFP64
暂无数据 查看

相关推荐

电子产业图谱

多年硬件从业经验,专注分享从研发到供应链,再到精益制造过程中的经验和感悟!