如何运行精确计时的功能?

时间:2011-11-01 20:44:08

标签: c# .net multithreading performance timer

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

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条消息的文件中读取(每条消息都有一个时间戳)。我需要尽可能接近文件所包含的时间重播这些消息。消息的时间戳记录在microsec中,但我只需要msec准确度。

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

我正在使用的机器具有超线程的QuadCore。使用for(int i = 0; .....)我可以获得0.5毫秒的准确度。然而,这是非常低效的,并且如果可能的话,更愿意使用更逼真,更便携的方法。

4 个答案:

答案 0 :(得分:5)

.NET,C#,甚至Windows通常都不是适合非常精细计时的实时操作系统。

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

您可以使用Stopwatch类相当准确地测量时间,但是在准确等待一定时间内通过时......没有内置机制。

如果你可以准确地概述你想要做什么,假设它不是运动控制,硬件接口等,那么可能有一个比依赖非常精确的定时器更好的解决方案。

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

答案 1 :(得分:1)

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

但是System.Diagnostics.Stopwatch应该在1ms左右给你精确度。

答案 2 :(得分:1)

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

您也可以使用多媒体计时器执行此操作,具有非常高的分辨率计时。见http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx

答案 3 :(得分:0)

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

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

基本上我将计时器的周期减少到我想要的周期,然后执行我的代码 - 它会定期回调到操作系统,以便操作系统能够体验到预期的时间间隔。还需要挂钩操作系统用来调整间隔的函数并相应地调整我的回调(假设我的代码总是以比操作系统想要的更高的频率运行)。实际上用它来通过打印机端口进行运动控制。从来没有把它变成已发布的软件,但确实得到了一个基本的CNC工作台。

Win98的代码停止运行良好,我再也没有尝试过。访问硬件变得更加复杂,几乎总是虚拟化"某种程度上来说。

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

相关问题