.NET 计时器,它们是按精确的时间间隔触发还是在处理后触发?间隔

发布于 2024-12-02 00:45:14 字数 1335 浏览 2 评论 0原文

这确实是一个足够简单的问题。

System.Timers 的时间间隔到底是如何工作的?

无论超时事件需要多长时间,它是否每秒触发 1 秒,或者是否需要例程首先完成然后重新启动间隔?

所以要么:

  1. 1秒....1秒....1秒等等
  2. 1秒+处理时间....1秒+处理时间....1秒+处理时间等等

我问的原因我知道我的“处理”时间远少于 1 秒,但我想每隔一秒就触发一次(或尽可能接近)。

我一直在使用 Thread.Sleep 方法,如下所示:

Thread.Sleep(1000 - ((int)(DateTime.Now.Subtract(start).TotalMilliseconds) >= 1000 ? 0 : (int)(DateTime.Now.Subtract(start).TotalMilliseconds)));

开始时间在例程开始时注册。 这里的问题是 Thread.Sleep 只能以毫秒为单位工作。因此,我的例程可以在 1000ms 或 1000.0234ms 的一小部分重新启动,这可能会发生,因为我的例程之一根据“TimeSpan”需要 0ms,但显然它使用了刻度/纳秒 - 这意味着计时已关闭并且没有每一秒都更长。 如果我能按滴答声或纳秒入睡,它就会爆炸。

如果数字 1 适用于 System.Timers 那么我想我已经排序了。 如果不是,我需要某种方法将线程“睡眠”到更高分辨率的时间,即刻度/纳秒。

你可能会问为什么我要执行内联 IF 语句,有时处理时间可能会超过 1000 毫秒,所以我们需要确保不会产生负数。此外,当我们确定这一点时,结束时间已略有变化 - 变化不大,但是,它可能会使线程延迟稍微长一些,导致整个后续休眠。

我知道,我知道,时间可以忽略不计......但是如果系统突然停滞几毫秒会发生什么......在这种情况下它可以防止这种情况。

更新 1好的

。所以我没有意识到你可以将 TimeSpan 作为计时值。所以我使用了下面的代码:

Thread.Sleep(TimeSpan.FromMilliseconds(1000) - ((DateTime.Now.Subtract(start).TotalMilliseconds >= 1000) ? TimeSpan.FromMilliseconds(0) : DateTime.Now.Subtract(start)));

如果我是对的,这应该允许我在恰好 1 秒或系统允许的尽可能接近的时间内重复线程。

So a simple enough question really.

How exactly does the interval for System.Timers work?

Does it fire 1 second, each second, regardless of how long the timeout event takes or does it require the routine to finish first and then restarts the interval?

So either:

  1. 1 sec....1 sec....1 sec and so on
  2. 1 sec + process time....1 sec + process time....1 sec + process time and so on

The reason I ask this is I know my "processing" takes much less than 1 second but I would like to fire it every one second on the dot (or as close as).

I had been using a Thread.Sleep method like so:

Thread.Sleep(1000 - ((int)(DateTime.Now.Subtract(start).TotalMilliseconds) >= 1000 ? 0 : (int)(DateTime.Now.Subtract(start).TotalMilliseconds)));

Where start time is registered at start of the routine. The problem here is that Thread.Sleep only works in milliseconds. So my routine could restart at 1000ms or a fraction over like 1000.0234ms, which can happen as one of my routines takes 0ms according to "TimeSpan" but obviously it has used ticks/nanoseconds - which would then mean the timing is off and is no longer every second. If I could sleep by ticks or nanoseconds it would be bang on.

If number 1 applies to System.Timers then I guess I'm sorted. If not I need some way to "sleep" the thread to a higher resolution of time i.e ticks/nanoseconds.

You might ask why I do an inline IF statement, well sometimes the processing can go above 1000ms so we need to make sure we don't create a minus figure. Also, by the time we determine this, the ending time has changed slightly - not by much, but, it could make the thread delay slightly longer causing the entire subsequent sleeping off.

I know, I know, the time would be negligible... but what happens if the system suddenly stalled for a few ms... it would protect against that in this case.

Update 1

Ok. So I didn't realise you can put a TimeSpan in as the timing value. So I used the below code:

Thread.Sleep(TimeSpan.FromMilliseconds(1000) - ((DateTime.Now.Subtract(start).TotalMilliseconds >= 1000) ? TimeSpan.FromMilliseconds(0) : DateTime.Now.Subtract(start)));

If I am right, this should then allow me to repeat the thread at exactly 1 second - or as close as the system will allow.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

來不及說愛妳 2024-12-09 00:45:14

如果您设置了 AutoReset = true; 那么您的理论 1 是正确的,否则您将不得不在代码中处理它 – 请参阅 MSDN 上的 Timer 文档

IF you have set AutoReset = true; then your theory 1 is true, otherwise you would have to deal with it in code – see the docuementation for Timer on MSDN.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文