毫秒等待的C#计时器

毫秒等待的C#计时器,c#,timer,C#,Timer,每n*x毫秒,我执行一个动作,其中n=0,1,2。。。;x是一些增量 示例-每25毫秒执行一次计算 var timer = new Timer(25); timer.Elapsed += (sender, eventArgs) => { DoCalc(); }; timer.Start(); 每次增量执行此操作所需的时间可能少于x秒。因此,我需要一种C#中

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

示例-每25毫秒执行一次计算

var timer = new Timer(25);
timer.Elapsed += (sender, eventArgs) =>
                     {
                         DoCalc();
                     };
timer.Start();
每次增量执行此操作所需的时间可能少于x秒。因此,我需要一种C#中的方法来等待剩余的(x-实际时间)毫秒

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

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

谢谢,
Kevin

在Windows这样的非实时操作系统中,很难达到这样的准确度。你最好的办法可能是查看多媒体计时器


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

在25毫秒时,您可能是.NET中可用计时器分辨率的错误端

然而,作为一个通用的解决方案,我可能会尝试一种不同的方法来进行“计算..等到25毫秒过去”的方法

更好的方法可能是在25ms触发器上使用一个触发器来触发计算

var timer = new Timer(25);
timer.Elapsed += (sender, eventArgs) =>
                     {
                         DoCalc();
                     };
timer.Start();
在上面的示例中,每隔25 ms将调用
DoCalc
方法(尽管存在计时器分辨率问题)。如果你的计算超出了分配的时间,你就需要考虑该怎么做。目前,上述代码将允许启动第二次计算,即使前一次计算尚未完成

我需要一种用C#表示的方法来等待剩余的(x-实际时间)毫秒

我想这是在Windows上运行的C#

这就是你的问题。Windows不是“实时”操作系统

如果需要毫秒级计时精度,最好将线程的优先级设置为极高,然后在查询高性能计时器(秒表)时忙碌等待

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

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


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

这是一个困难的问题,正如埃里克·利珀特和马特·伯兰所指出的,您的选择相当有限。基本上,你可以

var timer = new Timer(25);
timer.Elapsed += (sender, eventArgs) =>
                     {
                         DoCalc();
                     };
timer.Start();
  • 求助于使用多媒体计时器(google“multimedia timer component”或“winmm.dll”),虽然支持低至0.500毫秒的时间分辨率,但从Windows Vista开始不再推荐使用这种计时器,它需要Win32互操作,并且可能会显著提高CPU使用率,或者
  • 提出一种近似的时间切片算法,该算法将使用标准计时器(在多核台式机上,其分辨率通常为15.625 ms),根据自上次计时器计时以来所经过的期望时间和实际时间的差异,在每次计时时动态地改变计时器间隔(您可以使用高分辨率CPU性能计数器(例如秒表类)相当准确地测量这一点)
在您的示例用例中,后一种解决方案将在统计上为您提供一个40Hz的计时器,但是由于您使用的计时器的分辨率较低,您将有明显的抖动


这是一个折衷方案,这是你的选择。

这是我写的一个高精度计时器。我大致了解了准确的计时器精度有多重要?在像C#这样的高级语言中,在具有上下文切换的操作系统上进行垃圾收集,很难获得高分辨率的计时。也许你可以描述一下你为什么要这样做您认为您需要以如此高的时间分辨率执行操作吗?也许有更好的方法来实现您所需要的?或者有更好的方法来处理计时不准确的问题?我对系统的经验。我机器上的计时器的最大分辨率约为15毫秒(在Windows XP上)它只会在倍数上触发。因此,如果你将其设置为25毫秒,你可能会得到大约30毫秒的间隔。当然,这可能会随着硬件和操作系统的不同而有所不同。但是,这仍然比尝试计算完成计算后剩下的时间以及尝试将剩余时间的计时器设置为OP更准确最初建议的。@MattBurland-公平点-值得在目标环境中测试,但可能离分辨率太近而不准确。现在你这么说了,但我们创建了1毫秒实时(在可接受的抖动公差范围内)通过打破设备驱动程序中的所有规则,windows系统:)@Massif:windows Vista和更新版本利用了驱动程序签名强制执行,这为这种方法增加了额外的障碍。循环缓冲区的定义是什么?很抱歉,是这样的:我也在要点中添加了该评论。供参考