我目前正在研究一个对时间敏感的程序,重要的是我每秒都会从设备上读取数据。 我目前正在使用Timer,但我发现时间稳定增加了1 ms pr tick的间隔。这可能会导致问题,因为程序将运行很长时间。
Read Exe Time
是代码执行的时间。
Performing reading
在每个已过去的事件开始时。
我如何确保时钟不会增加,我可以理解,嘀嗒声可能不是精确的毫秒,但我继续攀爬似乎很奇怪。并且我的代码不会花费整整1000毫秒来执行,所以不是这样。 16.6分钟后读数将被推迟一秒钟。
Read Exe Time: 574.0637 ms
Performing reading: 22:58:39.696
Read Exe Time: 571.9422 ms
Performing reading: 22:58:40.697
Read Exe Time: 595.5333 ms
Performing reading: 22:58:41.697
Read Exe Time: 566.2602 ms
Performing reading: 22:58:42.698
Read Exe Time: 568.2275 ms
Performing reading: 22:58:43.698
Read Exe Time: 569.7573 ms
Performing reading: 22:58:44.700
Read Exe Time: 561.655 ms
Performing reading: 22:58:45.701
Read Exe Time: 567.8385 ms
Performing reading: 22:58:46.702
Read Exe Time: 584.8305 ms
Performing reading: 22:58:47.703
Read Exe Time: 588.754 ms
Performing reading: 22:58:48.703
Read Exe Time: 560.8154 ms
Performing reading: 22:58:49.704
Read Exe Time: 567.9324 ms
Performing reading: 22:58:50.705
Read Exe Time: 579.1354 ms
Performing reading: 22:58:51.706
Read Exe Time: 563.0227 ms
Performing reading: 22:58:52.707
Read Exe Time: 569.557 ms
Performing reading: 22:58:53.708
Read Exe Time: 560.707 ms
Performing reading: 22:58:54.708
Read Exe Time: 574.6268 ms
Performing reading: 22:58:55.709
Read Exe Time: 570.4872 ms
Performing reading: 22:58:56.710
Read Exe Time: 574.8388 ms
Performing reading: 22:58:57.710
Read Exe Time: 573.2054 ms
Performing reading: 22:58:58.710
Read Exe Time: 578.6189 ms
Performing reading: 22:58:59.711
Read Exe Time: 565.7442 ms
Performing reading: 22:59:0.711
Read Exe Time: 564.7523 ms
Performing reading: 22:59:1.712
Read Exe Time: 575.8134 ms
Performing reading: 22:59:2.713
Read Exe Time: 570.9416 ms
Performing reading: 22:59:3.713
Read Exe Time: 573.1493 ms
Performing reading: 22:59:4.714
Read Exe Time: 570.2831 ms
Performing reading: 22:59:5.714
Read Exe Time: 568.2672 ms
Performing reading: 22:59:6.715
Read Exe Time: 586.5607 ms
Performing reading: 22:59:7.715
Read Exe Time: 588.0465 ms
Performing reading: 22:59:8.715
Read Exe Time: 574.1118 ms
Performing reading: 22:59:9.716
代码
private void StartMeter()
{
this.Meter.Start();
this.ReadingTime = new Timer(1000);
this.ReadingTime.Elapsed += new ElapsedEventHandler(PerformReading);
this.ReadingTime.Start();
}
private void PerformReading(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Performing reading: " + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second + "." + DateTime.Now.Millisecond);
// Code here
}
更新: 如果我只是将时间设置为999毫秒,它将稳定地减少
Performing reading: 23:4:50.527
Read Exe Time: 562.7729 ms
Performing reading: 23:4:51.527
Read Exe Time: 566.8178 ms
Performing reading: 23:4:52.527
Read Exe Time: 562.3829 ms
Performing reading: 23:4:53.526
Read Exe Time: 567.9165 ms
Performing reading: 23:4:54.526
Read Exe Time: 561.1329 ms
Performing reading: 23:4:55.525
Read Exe Time: 562.9359 ms
Performing reading: 23:4:56.525
Read Exe Time: 560.4151 ms
Performing reading: 23:4:57.524
Read Exe Time: 561.0302 ms
Performing reading: 23:4:58.524
Read Exe Time: 561.5756 ms
Performing reading: 23:4:59.524
Read Exe Time: 565.2936 ms
Performing reading: 23:5:0.523
Read Exe Time: 561.8903 ms
Performing reading: 23:5:1.523
Read Exe Time: 561.8768 ms
Performing reading: 23:5:2.523
Read Exe Time: 562.3904 ms
Performing reading: 23:5:3.523
Read Exe Time: 562.3363 ms
Performing reading: 23:5:4.523
Read Exe Time: 561.6288 ms
Performing reading: 23:5:5.523
Read Exe Time: 560.4596 ms
Performing reading: 23:5:6.522
Read Exe Time: 562.34 ms
Performing reading: 23:5:7.522
Read Exe Time: 561.5994 ms
Performing reading: 23:5:8.522
Read Exe Time: 561.6811 ms
Performing reading: 23:5:9.521
Read Exe Time: 561.7427 ms
Performing reading: 23:5:10.521
Read Exe Time: 561.8044 ms
Performing reading: 23:5:11.520
Read Exe Time: 561.6246 ms
Performing reading: 23:5:12.520
Read Exe Time: 560.5753 ms
Performing reading: 23:5:13.520
Read Exe Time: 563.8604 ms
Performing reading: 23:5:14.520
Read Exe Time: 562.2606 ms
Performing reading: 23:5:15.534
Read Exe Time: 560.8377 ms
Performing reading: 23:5:16.534
Read Exe Time: 560.4553 ms
Performing reading: 23:5:17.534
Read Exe Time: 562.5534 ms
Performing reading: 23:5:18.533
Read Exe Time: 563.0269 ms
Performing reading: 23:5:19.532
Read Exe Time: 561.2851 ms
Performing reading: 23:5:20.532
Read Exe Time: 560.3442 ms
Performing reading: 23:5:21.531
Read Exe Time: 561.5201 ms
Performing reading: 23:5:22.530
Read Exe Time: 560.609 ms
Performing reading: 23:5:23.530
编辑:对于@PeterLuu
Performing reading: 22:44:45.13
Performing reading: 22:44:45.449
Performing reading: 22:44:45.879
Performing reading: 22:44:46.320
Performing reading: 22:44:46.761
Performing reading: 22:44:47.192
Performing reading: 22:44:47.631
Performing reading: 22:44:48.74
Performing reading: 22:44:48.577
Performing reading: 22:44:49.49
Performing reading: 22:44:49.637
代码
private void StartMeter()
{
DateTime now = DateTime.UtcNow;
NextTickTimeWholeSeconds = new DateTime(now.Ticks - (now.Ticks % TimeSpan.TicksPerSecond), now.Kind);
this.Meter.Start();
this.ReadingTime = new Timer(1000);
this.ReadingTime.Elapsed += new ElapsedEventHandler(PerformReading);
this.ReadingTime.Start();
ReadingTime.Interval = GetTimeToNextSecond();
}
private double GetTimeToNextSecond()
{
NextTickTimeWholeSeconds = NextTickTimeWholeSeconds.AddSeconds(1);
var interval = NextTickTimeWholeSeconds - DateTime.UtcNow;
return interval.Milliseconds < 1 ? GetTimeToNextSecond() : interval.Milliseconds;
}
private void PerformReading(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Performing reading: " + DateTime.UtcNow.Hour + ":" + DateTime.UtcNow.Minute + ":" + DateTime.UtcNow.Second + "." + DateTime.UtcNow.Millisecond);
// My code takes about 500-600 ms
ReadingTime.Interval = GetTimeToNextSecond();
}
答案 0 :(得分:2)
你可以将它基于下一秒的时间(例如,如果只有890毫秒直到点上的下一秒)并且每次迭代都以该间隔重新启动计时器以防止漂移。改编自Jared here之前的回答。这并不能提供精确到毫秒的精确度,但它可以防止您的时间漂移,并且事件将始终在点上消失#。
编辑:删除了不必要的行 - 您实际上不需要两次调用Start(),只需更改间隔即可,因为更改间隔会重新启动计时器。
编辑2:进行一些更改以使其在边缘情况下更准确(例如,防止连续多次触发)。
public class Meter
{
private Timer ReadingTime;
private DateTime NextTickTimeWholeSeconds;
public Meter() {
DateTime now = DateTime.UtcNow;
NextTickTimeWholeSeconds = new DateTime(now.Ticks - (now.Ticks % TimeSpan.TicksPerSecond), now.Kind);
ReadingTime = new Timer();
ReadingTime.AutoReset = false;
ReadingTime.Elapsed += new ElapsedEventHandler(PerformReading);
ReadingTime.Interval = GetTimeToNextSecond();
}
public void StartMeter()
{
ReadingTime.Start();
}
private double GetTimeToNextSecond()
{
NextTickTimeWholeSeconds = NextTickTimeWholeSeconds.AddSeconds(1);
var interval = NextTickTimeWholeSeconds - DateTime.UtcNow;
return interval.Milliseconds < 1 ? GetTimeToNextSecond() : interval.Milliseconds;
}
private void PerformReading(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Performing reading: " + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second + "." + DateTime.Now.Millisecond);
ReadingTime.Interval = GetTimeToNextSecond();
}
}
示例输出:
Performing reading: 18:11:47.10
Performing reading: 18:11:48.4
Performing reading: 18:11:49.10
Performing reading: 18:11:50.6
Performing reading: 18:11:51.9
Performing reading: 18:11:52.5
Performing reading: 18:11:53.10
Performing reading: 18:11:54.5
Performing reading: 18:11:55.9
Performing reading: 18:11:56.7
Performing reading: 18:11:57.7
Performing reading: 18:11:58.7
Performing reading: 18:11:59.7
Performing reading: 18:12:0.8
Performing reading: 18:12:1.7
Performing reading: 18:12:2.6
... about 50 seconds later ...
Performing reading: 18:12:50.1
Performing reading: 18:12:51.0
Performing reading: 18:12:52.0
Performing reading: 18:12:53.0
Performing reading: 18:12:53.999
Performing reading: 18:12:55.0
Performing reading: 18:12:56.0
Performing reading: 18:12:56.999
Performing reading: 18:12:58.0
Performing reading: 18:12:59.0
Performing reading: 18:13:0.0
Performing reading: 18:13:0.999
Performing reading: 18:13:2.0
Performing reading: 18:13:3.1
Performing reading: 18:13:4.0
Performing reading: 18:13:5.0
Performing reading: 18:13:6.0
Performing reading: 18:13:6.999
Performing reading: 18:13:8.0
Performing reading: 18:13:9.0
Performing reading: 18:13:10.0
Performing reading: 18:13:11.0
Performing reading: 18:13:12.1
Performing reading: 18:13:13.0
Performing reading: 18:13:13.999
Performing reading: 18:13:15.0
Performing reading: 18:13:16.0
Performing reading: 18:13:16.999
Performing reading: 18:13:18.0
Performing reading: 18:13:19.1
Performing reading: 18:13:20.0
Performing reading: 18:13:21.0
Performing reading: 18:13:21.999
Performing reading: 18:13:23.0
Performing reading: 18:13:24.0
Performing reading: 18:13:25.0
Performing reading: 18:13:26.0
Performing reading: 18:13:27.0
Performing reading: 18:13:28.0
Performing reading: 18:13:29.0
答案 1 :(得分:1)