我不能让计时器在每分钟,1:00,1:01,1:02等处每分钟发射一次。相反,当计时器每次迭代执行漂移几秒钟时
internal void StartTimer()
{
DateTime nowEastern = CalendarEntity.Calendar.GetEasternTime();
int secondsInterval = 5;
double additionalSeconds = secondsInterval - nowEastern.TimeOfDay.TotalSeconds % secondsInterval;
if (additionalSeconds == 0)
{
additionalSeconds = 1;
}
var nearestOnOneMinutes = new DateTime(
nowEastern.Year,
nowEastern.Month,
nowEastern.Day,
nowEastern.Hour,
nowEastern.Minute,
nowEastern.Second
).AddSeconds(additionalSeconds);
TimeSpan timeToStart = nearestOnOneMinutes.Subtract(nowEastern);
TimeSpan tolerance = TimeSpan.FromSeconds(1);
if (timeToStart < tolerance)
{
timeToStart = TimeSpan.Zero;
}
timer_onem = new System.Threading.Timer(OnTimedEvent, null,
(int)timeToStart.TotalMilliseconds, Timeout.Infinite);
}
private static void OnTimedEvent(object o)
{
var minute = DateTime.Now.Minute;
var second = DateTime.Now.Second;
if (minute != lastMinute && second % 60 < 2)
{
lastMinute = minute;
CodeToExecute();
}
}
static void CodeToExecute()
{
double tms = 60000;
// code here
int wait = 60 - System.DateTime.Now.Second;
timer_onem.Change(Convert.ToInt64(tms) - wait, Timeout.Infinite);
}
编辑1
我更改了间隔,使其每秒触发一次,然后检查分钟是否已更改。仍漂移
timer_onem = new System.Threading.Timer(OnTimedEvent, null,
(int)timeToStart.TotalMilliseconds, 1000);
private static void OnTimedEvent(object o)
{
var minute = DateTime.Now.Minute;
if (minute != lastMinute)
{
lastMinute = minute;
CodeToExecute();
}
}
private static void CodeToExecute()
{
if (bGenerate)
{
double tms = 1000;
// code
timer_onem.Change(Convert.ToInt64(tms), 1000);
}
}
答案 0 :(得分:3)
Timer
仅保证不会比Interval
更快。
所以你需要打电话,说每一秒,然后检查整整一分钟。
为了获得更好的精度,你必须每1/2秒或更好地检查一次。
信息理论的基本规则是,要以给定的分辨率(在您的情况下为1秒)进行测量,您需要采样的分辨率优于分辨率的两倍。因此,要测量20kHz,您需要的采样率优于2x20kHz,比如44.1kHz。 (识别数字?)
如果您不想通过经常来调用一个精确的时间点,那么您可以编写一些更复杂的代码。 Tick
将剩余时间的Timer.Interval
重置为一半,直到下一整分钟,直到500码以下为止。
但是,在设置预期时间的过程中,代码中存在相当复杂的事情;确保它们不是真正的问题。除非你收集&#39; 收集&#39; &#39; 错误..