【问题标题】:Need events to execute on timer events, metronome precision需要事件来执行定时器事件,节拍器精度
【发布时间】:2011-01-28 15:05:31
【问题描述】:

我设置了一个计时器来调用我的应用程序中的事件。问题是事件执行被其他 Windows 操作倾斜。前任。打开和窗口,加载网页。我需要事件每次都准时执行。

当我第一次设置应用程序时,使用声音文件(如节拍器)来听均匀触发,在稳定状态下,它会立即触发,但是一旦在 windows 环境中执行某些操作,声音就会变慢,然后有点加速赶上。

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

(秒):(毫秒)

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

所以我认为计时器每次都会继续以相同的毫秒触发,但它的事件被其他 Windows 操作倾斜以触发时间。 这不是一个巨大的偏差,但对于我需要完成的事情,这是不可接受的。

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

谢谢。

【问题讨论】:

  • 再读一遍后看到的东西:你以什么方式写入日志?如果您通过刷新文件访问来执行此操作,则仅磁盘写入就可以在几毫秒内完成。所以你真的应该只记录到内存。

标签: .net events multithreading timer listener


【解决方案1】:

如果可能的话,做到这一点可能非常、非常棘手。某些音频处理应用程序确实很难做到这一点。标准计算机设置并不完全适合这种实时操作,因为您无法控制在后台运行多少线程/进程。

但是,作为第一次尝试,您可以使用循环而不是异步触发器。请注意,这可能会增加 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/,但其中的代码非常简单,基本上以秒为单位为您提供了自计时器以非常高的精度启动以来的时间。

您可能还希望为您的进程提供更高的优先级,这样其他进程就不会停止您的进程。

【讨论】:

  • Win32多媒体定时器服务怎么样?有没有一个很好的例子,如何将应用程序设置为更高的优先级?
  • 首先可以使用timeBeginPeriod具体调整timeGetTime的精度。请注意,Windows 多媒体计时器的默认精度很差(大约 10 毫秒!),而 QPF 以微秒为单位。请参阅 MSDN msdn.microsoft.com/en-us/library/dd757629(VS.85).aspx 上的此链接。但是,我以前从未使用过。再想想,我不会弄乱线程优先级的。
  • 播放 WAV 文件与 MIDI 声音是否也有问题?或者只是我播放 WAV 文件的方式?相信我用过 System.Media.SoundPlayer。不要在我面前有代码。这是我试过的多媒体计时器,codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx
  • 由于声音驱动程序等原因会有额外的延迟。我相信这也有点依赖于硬件。在尝试使用基于计算机的 DJ 工具时,我遇到了不同声卡上不同延迟的问题,所以是的,这可能是个问题。您最初发布的内容与计时器回调的测量有关,但是 - 实际上并未响应它们,所以这是一个完全不同的问题。尝试做一些非常简单的事情而不是播放声音,例如更改矩形或其他东西的颜色。
  • 我在 Windows 窗体上显示了每次点击的时间。仍然看到滞后,但没有那么糟糕。想知道延迟是否没有声音那么大。想知道耳朵是否真的在感知毫秒变化,或者声音是否比计时器的事件调用者滞后更多。
【解决方案2】:

正如您所观察到的,我希望计时器能够非常接近准时触发。但是,即使计算机受处理器限制,也会受到影响。

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

我认为您不太可能让 UI 准确地按时更新,因为在任何特定时刻发生的事情都有太多的可变性。在单处理器机器上尤其如此。

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

【讨论】:

    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 2017-10-21
    相关资源
    最近更新 更多