c# - .NET 计时器,它们是在准确的时间间隔触发还是在处理 + 间隔后触发

标签 c# multithreading timer thread-sleep

真的是一个非常简单的问题。

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 只在几毫秒内起作用。因此,我的例程可以在 1000 毫秒或 1000.0234 毫秒的一小部分重新开始,这可能会发生,因为根据“TimeSpan”,我的例程之一需要 0 毫秒,但显然它使用了滴答/纳秒 - 这意味着计时已关闭并且没有每秒更长。 如果我能在滴答声或纳秒内休眠,它就会爆炸。

如果第 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 秒或系统允许的最短时间内重复线程。

最佳答案

如果您设置了 AutoReset = true; 那么您的理论 1 为真,否则您将不得不在代码中处理它 – 参见 the docuementation for Timer on MSDN .

关于c# - .NET 计时器,它们是在准确的时间间隔触发还是在处理 + 间隔后触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7218306/

相关文章:

c# - 将字符串转换为 double : input string was not in a correct format

java - finalize() 在 Java 中如何工作?

objective-c - Objective-C:完成间隔计时器

c++ - boost::condition::notify_all 是否保证监听器线程在返回之前将获取锁?

flutter - 如何在 Flutter App 中按时间注销?

c - 错误的脉冲序列定时

c# - 使用 SimpleInjector 为 AccountController/ApplicationUserManager 注册 UserStore

c# - 如何在 ASP.NET 中将对象保存到 session 并在 View 中访问它

c# - 通过 `Configuration.Install.Installer` 安装长期运行的服务时如何将参数传递给 `installutil`

multithreading - 为每个对象加载生成一个新线程