c# 微秒级定时器,高精度定时器

整个代码,封装成类
using System;
using System.Runtime.InteropServices;namespace winTest
{/// <summary>/// 基于系统性能计数器的定时器,计数单位是1微秒=1/1000毫秒/// 注意:该定时器会独占一个CPU核心,尝试定时器与主程序运行在同一核心将导致程序失去响应/// </summary>public class MTimer{/// <summary>/// 获取当前系统性能计数/// </summary>/// <param name="lpPerformanceCount"></param>/// <returns></returns>[DllImport("Kernel32.dll")]private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);/// <summary>/// 获取当前系统性能频率/// </summary>/// <param name="lpFrequency"></param>/// <returns></returns>[DllImport("Kernel32.dll")]private static extern bool QueryPerformanceFrequency(out long lpFrequency);/// <summary>/// 指定某一特定线程运行在指定的CPU核心/// </summary>/// <param name="hThread"></param>/// <param name="dwThreadAffinityMask"></param>/// <returns></returns>[DllImport("kernel32.dll")]static extern UIntPtr SetThreadAffinityMask(IntPtr hThread, UIntPtr dwThreadAffinityMask);/// <summary>/// 获取当前线程的Handler/// </summary>/// <returns></returns>[DllImport("kernel32.dll")]static extern IntPtr GetCurrentThread();/// <summary>/// 是否销毁定时器/// </summary>private bool _Dispose = false;/// <summary>/// 是否正在运行定时器/// </summary>private bool _BRunTimer = false;/// <summary>/// 首次启动延时(微秒)/// </summary>private uint _Delay = 0;/// <summary>/// 定时器周期(微秒)/// </summary>private long _Period = 10;/// <summary>/// 定时器运行时独占的CPU核心索引序号/// </summary>private byte _CpuIndex = 0;/// <summary>/// 系统性能计数频率(每秒)/// </summary>private long _Freq = 0;/// <summary>/// 系统性能计数频率(每微秒)/// </summary>private long _Freqmms = 0;/// <summary>/// 回调函数定义/// </summary>private OnTickHandle Tick;/// <summary>/// 根据CPU的索引序号获取CPU的标识序号/// </summary>/// <param name="idx"></param>/// <returns></returns>private ulong GetCpuID(int idx){ulong cpuid = 0;if (idx < 0 || idx >= System.Environment.ProcessorCount){idx = 0;}cpuid |= 1UL << idx;return cpuid;}/// <summary>/// 定时器构造函数/// </summary>/// <param name="delay">首次启动定时器延时时间(微秒)</param>/// <param name="period">定时器触发的周期(微秒)</param>/// <param name="cpuIndex">指定定时器线程独占的CPU核心索引,必须>0,不允许为定时器分配0#CPU</param>/// <param name="tick">定时器触发时的回调函数</param>public MTimer(uint delay, uint period, byte cpuIndex, OnTickHandle tick){Tick = tick;_Delay = delay;_Period = period;_CpuIndex = cpuIndex;long freq = 0;QueryPerformanceFrequency(out freq);if (freq > 0){_Freq = freq;_Freqmms = freq / 1000000;//每微秒性能计数器跳跃次数}else{throw new Exception("初始化定时器失败");}if (_CpuIndex == 0){throw new Exception("定时器不允许被分配到0#CPU");}if (_CpuIndex >= System.Environment.ProcessorCount){throw new Exception("为定时器分配了超出索引的CPU");}}private System.Threading.Thread _threadRumTimer;/// <summary>/// 开启定时器/// </summary>public void Open(){if (Tick != null){_threadRumTimer = new System.Threading.Thread(new System.Threading.ThreadStart(RunTimer));_threadRumTimer.Start();}}/// <summary>/// 运行定时器/// </summary>private void RunTimer(){UIntPtr up = UIntPtr.Zero;if (_CpuIndex != 0)up = SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(GetCpuID(_CpuIndex)));if (up == UIntPtr.Zero){throw new Exception("为定时器分配CPU核心时失败");}long q1, q2;QueryPerformanceCounter(out q1);QueryPerformanceCounter(out q2);if (_Delay > 0){while (q2 < q1 + _Delay * _Freqmms){QueryPerformanceCounter(out q2);}}QueryPerformanceCounter(out q1);QueryPerformanceCounter(out q2);while (!_Dispose){_BRunTimer = true;QueryPerformanceCounter(out q2);if (q2 > q1 + _Freqmms * _Period){//***********回调***********//if (!_Dispose)Tick(this, (q2 - q1) / (_Freqmms * _Period), (q2 - q1) / _Freqmms);q1 = q2;//System.Windows.Forms.Application.DoEvents();//会导致线程等待windows消息循环,时间损失15ms以上}_BRunTimer = false;}}/// <summary>/// 销毁当前定时器所占用的资源/// </summary>public void Dispose(){_Dispose = true;while (_BRunTimer)System.Windows.Forms.Application.DoEvents();//在工作未完成之前,允许处理消息队列,防止调用者挂起if (_threadRumTimer != null)_threadRumTimer.Abort();}/// <summary>/// 定时器事件的委托定义/// </summary>/// <param name="sender">事件的发起者,即定时器对象</param>/// <param name="JumpPeriod">上次调用和本次调用跳跃的周期数</param>/// <param name="interval">上次调用和本次调用之间的间隔时间(微秒)</param>public delegate void OnTickHandle(object sender, long JumpPeriod, long interval);}
}

下面是测试代码

     MTimer m;private void fun(object sender, long JumpPeriod, long interval){Console.WriteLine(DateTime.Now.Millisecond);}private void OnOpen(object sender, EventArgs e){m = new MTimer(100, 500, 1, fun);m.Open();}private void OnClose(object sender, EventArgs e){m.Dispose();}

实现的效果是一秒输出当前毫秒数2000次。

写在最后,些方法要求电脑cpu核心数量大于1

c#实现 微秒级定时器,高精度定时器相关推荐

  1. Windows高精度微秒级(并发)定时器实现

    自从上次封装微秒延时函数后,利用空闲时间试着封装一个微秒定时器(类似MFC定时器形式)使用起来效果还不错. 关于定时器的几点介绍:    1.设计采用了自动释放定时器节点方式(增加虚析构函数在内部做相 ...

  2. 无需另配定时器在STM32 HAL下实现微秒级延时(兼容FreeRTOS)

    目录 前言 一.代码部分 二.使用和验证 1.引入头文件 2.初始化 3.使用和验证 三.可移植性 总结 前言 接触HAL库差不多两年了,一直苦于HAL库没有自带微秒级的延时,网上的前辈们给出的解决方 ...

  3. Linux下的微秒级定时器: usleep, nanosleep, select, pselect

    Linux下的微秒级定时器: usleep, nanosleep, select, pselect 标签: linuxnulldelaystructdate 2012-02-07 23:29 4979 ...

  4. Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现

    转自:http://blog.csdn.net/droidphone/article/details/8074892 上一篇文章,我介绍了传统的低分辨率定时器的实现原理.而随着内核的不断演进,大牛们已 ...

  5. 多媒体高精度定时器介绍

    一:背景 在Windows系统下播放多媒体时,需要去精确控制播放过程,如果用Windows产生的WM_TIMER常规定时器来实现,多媒体画面会出现断断续续的现象,原因在于WM_TIMER只能提供大于等 ...

  6. 高精度定时器学习(通过官方手册学习)

    高精度定时器学习 功能描述 一般说明 HRTIM引脚和内部信号 时钟 Timer A..E timing units 翻转事件 功能描述 一般说明 HRTIM可以划分为几个模块: •主定时器 •计时单 ...

  7. linux 定时器 jiffies,linux下jiffies定时器和hrtimer高精度定时器(示例代码)

    一.jiffies定时器,HZ=100,精度只能达到10ms. 注:采用jiffies+msecs_to_jiffies(xx ms);可做到ms级,不过精度不够 #include //DO--> ...

  8. Linux 内核定时器使用 二 高精度定时器 hrtimer 的用例

    之前介绍了timer_list内核定时器,它的精度在毫秒级别,再高一点它就无能为力了,所幸内核提供了高精度定时器 hrtimer. 源文件在linux/kernel/hrtimer.c中.接口简单.下 ...

  9. hpet 定时器中断 8259 linux,[OSDEV]编程高精度定时器(HPET)

    高精度定时器HPET和I/O APIC一样,用的是内存映射,映射的地址保存在BIOS提供的ACPI表格中 我们首先来获取这个地址 获取HPET的I/O内存地址 先来看一下文档的30-31页: 关键就是 ...

最新文章

  1. 服务器怎么设置网站写入权限,如何设置服务器写入权限设置方法
  2. linux mint 下载辅助工具,Linux Mint 18.2 下载工具AxeluGet
  3. ITK:重新缩放图像
  4. L 1 ,L 2 参数正则化
  5. while循环语句用法_EXCEL退出DO LOOP循环语句|until、while
  6. PHP异常与错误处理机制
  7. php驱动下载好后安装在哪里,没网如何安装网卡驱动
  8. 黑客都怎么制作外挂?C++黑客编程收集的源码集合
  9. 什么是UDS诊断协议?
  10. 微信小程序高仿京东分类效果完整版(超详细)
  11. python实现图片嗅探工具——自编driftnet
  12. 利用css制作二级下拉菜单
  13. echart自定义动画_echarts动画效果
  14. 等待事件buffer busy waits
  15. php 同步微信大量粉丝在数据表,微粉丝—— 微信加粉统计系统/复制统计准确率90%以上...
  16. Firefox旧版本及插件安装下载
  17. 产品思维已死? 我看未必
  18. esp32/8266 查询海事网https://www.cnss.com.cn/tide/港口潮汐数据
  19. HPB芯链 -- 共识算法选举机制描述
  20. Mac OS GMT安装与使用

热门文章

  1. winndows7、office2013 激活信息还原
  2. 毕业一周年,工作一周年,感想理解篇
  3. ACP(MaxCompute篇)-使用MMA迁移工具上传数据
  4. Android Studio编译无错,但在模拟器上无法运行App
  5. python实现抢票github_​两大 Python 抢票神器霸榜 GitHub
  6. C语言中变量声明和变量定义的区别
  7. fat32文件系统的实现与buddy算法
  8. TiDB(1):TiDB简介
  9. linux route 刷新_LINUX常用命令-route
  10. 【ONNXRuntime】Win10 GPU环境 ONNXRuntime下载与VS开发配置