了解多媒体计时器的奇怪行为

时间:2013-12-03 04:48:54

标签: c# performance timer

我在我的应用程序(C#.NET)中使用多媒体计时器来提高计时器的准确度并达到1 ms的计时器频率。到目前为止,我的应用程序一直运行良好,直到最近才开始表现得很奇怪。我试图了解我的申请有什么问题。以下是采取的步骤

  1. 定时器频率设置为1 ms,每1ms调用一次回调
  2. 有4个线程,每个线程都创建自己的计时器对象。它们都设置为在1ms后调用回调。这些是个别实例,不共享。
  3. 旧的代码执行时间约为0.3毫秒。这个工作正常,直到下一步。
  4. 应用程序代码已更改。定时器回调函数现在需要大约1.2 ms才能执行。这显然是个问题。 (我将在稍后优化代码。但现在我只想了解多媒体计时器行为)
  5. 只有第一个线程正在调用定时器回调,而对于其他线程,回调只被调用两次或三次,之后就不会调用回调。
  6. 看起来对于其他线程,计时器甚至错过了(?)而且它无法赶上。 (它错过了每次中断)。
  7. 请您解释一下计时器对象的行为。所有线程实际上都指向同一个定时器对象,因为它只有一个进程吗? 为什么其他线程没有调用定时器回调?

2 个答案:

答案 0 :(得分:6)

多媒体计时器的最大分辨率为1毫秒。这导致可编程中断控制器(在硬件上)每1ms触发一次。如果你启动了4个线程,所有线程都创建了1ms时间的计时器,这并不意味着你将每毫秒获得一次以上的事件。

我建议您阅读MSDN上的Why are the Multimedia Timer APIs (timeSetEvent) not as accurate as I would expect?博文。

这里适用的一些引用(强调我的):

  

MM Timer API允许开发人员重新编程Programmable   机器上的中断控制器(PIC)。您可以指定新的   计时器分辨率通常,我们将其设置为1毫秒。这个   是计时器的最大分辨率。 我们无法获得亚毫秒级   精确度。这种重新编程PIC的效果是导致   操作系统更频繁地唤醒。这增加了我们的机会   我们将在操作系统通知应用程序   指定。 我说,“增加机会”因为我们仍然不能   保证我们实际上会收到通知   当我们告诉它时,操作系统会起作用。

  

请记住,PIC用于唤醒操作系统,以便它可以决定   接下来应该运行什么线程。操作系统使用一些非常复杂的规则   确定接下来要占用处理器的线程。两个   操作系统查看的内容,以确定它是否应该运行一个线程或   不是线程优先级和线程量。

因此,即使您将分辨率降低到最大1ms,也不能保证您的线程将被选择用于执行其工作。

答案 1 :(得分:0)

我想您使用的系统计时器在单个专用线程上运行回调。

然后将系统间隔设置为1 ms。在更改之前,回调需要0.3毫秒才能完成,因此4个线程的回调需要4 * 0.3 = 1.2毫秒才能完成。因此,他们设法在1-2个时间间隔内完成操作,之后都可以重新开始。

但是更改后,每个回调本身需要1.2毫秒。因此,我们有从线程2-4运行回调的请求,而有从线程1运行的另一个请求(因为时间间隔用完了)。之后,它取决于所使用的计时器,它将服务于哪个请求。原来是第一个线程。