C#毫秒等待计时器

本文关键字:计时器 等待 | 更新日期: 2023-09-27 18:29:12

每n*x毫秒,我执行一个操作,其中n=0,1,2。。。;x是某个增量。

示例-我每25毫秒进行一次计算。

此操作每次增量所需时间可能少于x秒。因此,我需要C#中的方法来等待剩余的(x-actual_time)毫秒。

示例-如果计算只需要20毫秒,我需要再等5毫秒才能重新运行计算。

请告知。

谢谢,Kevin

C#毫秒等待计时器

我需要C#中的一种方法来等待剩余的(x-actual_time)毫秒。

我认为这是在Windows上运行的C#。

这就是你的问题。Windows不是一个"实时"操作系统。

如果您需要毫秒级的计时精度,最好的方法是将线程的线程优先级设置得极高,然后在查询高性能计时器(Stopwatch)时忙于等待。

您不能屈服于另一个线程;在操作系统上下文切换它之前,另一个线程可能会运行长达16毫秒,当然,除非你是优先级最高的线程,否则你不能保证在这16毫秒结束后控制权会回到你手中。

现在,将线程优先级设置得很高,然后忙于等待是你可能做的最粗鲁的事情之一;从本质上讲,你将控制用户的机器,不允许他们用它做任何其他事情

因此,我要做的是完全放弃这一行动方案。或者,(1)考虑获得一个为实时流程控制而设计的操作系统,如果这实际上是你的应用程序,而不是一个为多任务处理一系列业务应用程序而设计的系统。或者(2)放弃每25毫秒执行一次操作的要求。只需执行一次计算,然后将量子的剩余部分交给另一个线程。当你恢复控制时,看看你是否已经屈服超过25毫秒;如果没有,就再次屈服。如果有,则重新开始并执行计算。

在像Windows这样的非实时操作系统中,很难达到这种精度。你最好看看多媒体计时器。

其他.NET计时器将没有您需要的那种分辨率。

在25ms时,您可能在.Net.中的可用计时器的分辨率方面出错

然而,作为一个通用的解决方案,我可能会尝试一种不同于你的"计算……等待25毫秒"方法的方法。

更好的方法可能是在25ms触发器上使用System.Timers.Timer来触发计算。

var timer = new Timer(25);
timer.Elapsed += (sender, eventArgs) =>
                     {
                         DoCalc();
                     };
timer.Start();

在上面的例子中,DoCalc方法将每25ms调用一次(尽管存在定时器分辨率问题)。如果您的计算超出了分配的时间,您需要考虑该怎么办。目前,上述代码将允许开始第二次计算,即使前一次计算尚未完成。

正如Eric Lippert和Matt Burland所指出的,这是一个困难的问题,您的选择相当有限。基本上,你可以选择

  • 使用多媒体计时器(谷歌"多媒体计时器组件"或"winmm.dll"),尽管支持低至0.500毫秒的时间分辨率,但从Windows Vista起不再推荐使用,需要Win32互操作,并且可能会显著提高CPU使用率,或者
  • 提出了一种近似的时间切片算法,该算法将使用标准定时器(其分辨率在多核台式机上通常为15.625ms),根据自上次计时器计时以来所需时间和实际时间的差异,在每次计时时动态更改计时器间隔(您可以使用高分辨率CPU性能计数器(例如Stopwatch类)来相当准确地测量这一点)

后一种解决方案将在您的示例用例中为您提供一个40Hz的计时器,但由于您使用的计时器分辨率较低,您会有显著的抖动。

这是一个权衡,决定权在你。

这是我写的一个高精度计时器。我大致得到<25ms间隔的平均1ms精度。但如果Windows很忙,它可能会晚到。它相当依赖于CPU利用率。随意使用。当下一次滴答声超过15毫秒时,它使用Sleep(1),然后使用SpinUntil(根据需要产生)来控制CPU使用。使用.NET4功能。

链接:高精度定时器