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

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

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

你能解释一下计时器对象的行为吗? 所有线程实际上都指向同一个计时器对象,因为它只有一个进程吗? 为什么其他线程没有调用定时器回调?

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

我鼓励您阅读为什么多媒体计时器API(timeSetEvent)不如我预期的那样准确? MSDN上的博客文章。

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

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

和:

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

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