需要在定时器事件上执行事件,节拍器精度

时间:2010-03-17 14:59:03

标签: .net events multithreading timer listener

我设置了一个计时器来调用我的应用程序中的事件。问题是事件执行受到其他Windows操作的影响。防爆。打开和窗口,加载网页。我需要事件按时完全按时执行。

当我第一次设置应用程序时,使用一个声音文件,就像一个节拍器来聆听均匀的发射,在一个稳定的状态下,它正好点亮,但是尽快在窗口环境中做一些事情,声音会慢一些,然后有点加速,以赶上。

所以我在事件中添加了一个记录方法,以便计时器滴答。从该数据看,计时器不受Windows应用程序的影响,但我的应用程序事件调用正在受到影响。我通过检查事件中的datetime.now来确定这一点,如果我将其设置为250毫秒,即每秒4次点击。你得到的数据如下。

(秒):( MS)

1:000 1:250 1:500 1:750

2:000 2:250 2:500 2:750

3:000 3:250 3:500 3:750

(假设我执行了一些windows事件)(时间会偏斜)

4:122 4:388 4:600 4:876

(停止做我在windows上做的事情) (为了简化数据,我的名单缩短了30秒)

5:124 5:268 5:500 5:750

(你会花时间回到开头的同一毫秒)

6:000 6:250 6:500 6:750

7:000 7:250 7:500 7:750

所以我认为计时器每次都会以相同的毫秒继续发射,但是其他窗口操作正在歪斜时间。 它不是一个巨大的倾斜,但对于我需要完成的事情,它是不可接受的。

我是否可以在.NET中做什么,希望使用XAML / WPF应用程序,这将纠正事件的偏差?

THX。

2 个答案:

答案 0 :(得分:2)

如果可能的话,做正确的事情可能非常非常非常棘手。某些音频处理应用程序真的很难做到这一点。标准计算机设置并非完全针对此类实时操作,因为您无法控制在后台运行的线程/进程数。

但是,作为第一次尝试,您可以使用循环而不是异步触发器。请注意,这可能会在CPU上变得很重,但仍然无法保证精确的计时。伪代码:

forever
{
     // This will bring your precision down to the level of thread 
     // timing precision
     Sleep(0); 

     LastTime = GetPerformanceTimer();
     if(LastTime > NextInterval)
     {
         // Play sound, update last time
     }
}

其中GetPerformanceTimer是某种基于QueryPerformanceCounter的方法。我写了一个非常简单的探查器http://www.emphess.net/2009/03/04/a-very-simple-profiler/,但是那里的代码非常简单,基本上给你的时间以秒为单位,自定时器开始以非常高的精度。

您可能还希望为您的流程提供更高的优先级,以便其他流程不会拖延您的流程。

答案 1 :(得分:1)

正如您所观察到的那样,我希望计时器能够准确地准时发射。但是,如果计算机受处理器限制,甚至可能会受到影响。

您希望事件准确地按时在UI线程上发生,这将是一个问题。更新UI的代码必须在UI线程上执行。如果计时器触发时UI线程上发生了其他任何事情,则计时器的更新操作必须等待。

我认为你不可能准确地按时更新用户界面,因为在任何特定时刻发生的事情变化太大。在单处理器机器上尤其如此。

如果您不需要更新UI,则可以通过使用System.Threading.Timer和回调方法reather而不是使用其中一个使用事件的计时器来获得稍微更一致的响应。不过,如果你能让任何基于计时器的方法在这个应用程序中可靠地工作,我会感到非常惊讶。