如何精确计时地运行一个函数

本文关键字:一个 函数 运行 何精确 | 更新日期: 2023-09-27 18:13:28

我需要一个函数在+/- 1ms内的精确时间运行。我尝试了以下操作,但最终执行之间的最小时间为15ms。

void Main()
{
    System.Timers.Timer timer = new System.Timers.Timer(1);   // executes every 15ms
    timer.Elapsed += new System.Timers.ElapsedEventHandler(myFunction);
    System.Timers.Timer timer2 = new System.Timers.Timer(5);   // executes every 15ms
    timer2.Elapsed += new System.Timers.ElapsedEventHandler(myFunction);
    System.Timers.Timer timer2 = new System.Timers.Timer(20);   // executes every 31ms
    timer3.Elapsed += new System.Timers.ElapsedEventHandler(myFunction);
    timer.Start();
    timer2.Start();
    timer3.Start();
}
void myFunction()
{
    doWord();
}

使用Thread.Sleep()得到相同的结果。

应用概要。

我将读取一个包含1553条消息(每个消息都有时间戳)的文件。我需要用尽可能接近文件所包含的时间重播这些消息。消息的时间戳以微秒为单位记录,但我只需要微秒的精度。

这是使用DDC 1553卡(PCI卡)完成的。我有一个分析器,它允许我查看消息,包括消息之间的增量时间,以测量我的准确性。

我使用的机器有一个超线程的四核。使用a for(int i=0;…)我可以把精度调到0.5毫秒。然而,这是非常低效的,如果可能的话,我宁愿使用更现实的、甚至更可移植的方法。

如何精确计时地运行一个函数

。. NET, c#,甚至一般的Windows都不是适合精确计时的实时操作系统。

最差的选择包括使用Timer类和Thread.Sleep()类。

您可以使用Stopwatch类相当准确地测量计时,但就准确地等待一组时间通过而言…没有内置机制。

如果你能准确地勾勒出你想要做的事情,假设它不是运动控制,硬件接口等,可能有一个比依赖非常精确的计时器更好的解决方案。

更新;Neal:如果你是以时间敏感的方式与硬件进行交互,你应该使用不同的解决方案。您可以使用Stopwatch进行紧密循环,但是只要您这样做,它就会使用大量CPU。它可能不够准确。例如:一个PIC芯片,一个FPGA,一个I/O卡或接口,基本上任何其他的。

您可以使用高分辨率计时器,但它取决于设备。你得去查询一下。有关说明,请参阅此MSDN页面:http://msdn.microsoft.com/en-us/library/aa964692%28v=vs.80%29.aspx

但是System.Diagnostics.Stopwatch应该已经给你接近1ms的精度了

您可以使用System.Threading.Timer,它具有合理的准确性。请记住,它不会发布到UI线程上,所以你需要正确地委托任何UI交互。

您也可以使用多媒体计时器来做到这一点,它具有非常高的分辨率定时。见http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx

我不知道如何在现代版本的Windows中做这样的事情-只是偶然发现了这个老问题,并回忆起我在很久以前遇到过类似的问题…

回到石器时代(win3.11和后来的Win95),我能够获得非常高和可重复的实时性能(10kHz没有问题,抖动也相当不错-在90MHz的奔腾微秒范围内)通过重新编程实时中断和挂钩到定时器的不可屏蔽中断。当时这涉及到VxD(虚拟设备驱动程序)能够直接访问计时器。还需要获得专用的共享内存空间和汇编代码(可能将汇编与C/c++混合使用-显然,频率越高,循环需要越紧密)。

基本上,我将计时器的周期减少到我想要的,然后执行我的代码——它会周期性地回调到操作系统,这样操作系统就会体验到它所期望的时间间隔。还需要挂钩操作系统用来调整间隔和相应调整回调的函数(假设我的代码总是以高于操作系统所需的频率运行)。实际上是用它来通过打印机端口进行运动控制。从来没有让它成为发布的软件,但确实得到了一个基本的工作台CNC运行。

代码在Win98下就不能正常工作了,我再也没有尝试过。访问硬件变得越来越复杂,而且几乎总是以某种方式"虚拟化"。

当我试图在专用的RTOS环境之外获得某种类型的RTOS性能时,我会首先查看设备驱动程序编程和可能的游戏(例如Direct X)。