C# 每分钟计时一次
我不能让计时器在每分钟1:00、1:01、1:02等时触发一次。相反,当计时器每次迭代执行漂移几秒时C# 每分钟计时一次,c#,multithreading,timer,C#,Multithreading,Timer,我不能让计时器在每分钟1:00、1:01、1:02等时触发一次。相反,当计时器每次迭代执行漂移几秒时 internal void StartTimer() { DateTime nowEastern = CalendarEntity.Calendar.GetEasternTime(); int secondsInterval = 5; double additionalSeconds = secondsInterval - now
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/2秒或更高的时间检查一次
信息论的一条基本规则是,要以给定的分辨率(在您的情况下为1秒)进行测量,您需要以比该分辨率高一倍的分辨率进行采样。因此,要测量20kHz,您需要一个比2x20kHz(例如44.1kHz)更好的smpling速率。(认得数字吗?)
如果你不想经常称之为“一个时间点”的话,您可以编写更复杂的代码,在每个勾选
时将计时器重置。间隔
在剩余时间的一半以下,直到下一整分钟,直到小于500ms
但是,在设置预期时间时,代码中会发生相当复杂的事情;确保它们不是真正的问题。由于计时器的精度不高,不应出现不断增长的漂移,除非您“收集”错误。请参见编辑1。这似乎无助于增加定时事件的频率。你是说为了让我在一个整数分钟的边界上以+/-1秒的漂移(或60000毫秒)执行某些操作,我必须每500毫秒触发一次计时器?这似乎很荒谬。所以1:01:01,1:02:02,1:03:02,1:04:01是可以的,但是我得到了1:01:02,1:02:04,1:03:06,等等,在秒上单调递增。这是信息论的一条基本规则,它说,要用给定的分辨率进行测量,你需要用两倍以上的分辨率进行采样。因此,要测量20kHz,您需要比2x20kHz更好,比如44kHz。(识别数字?)当然,如果只需要测量一个时间点,这是浪费;请参阅我的最后一段,了解一个优化但仍然简单的算法。-不确定,但如果不是,可能代码中的其他东西可能是罪魁祸首。事实上,漂移的增长肯定有不同的原因。我建议您注销预期时间,看看它们是否合理。您执行的代码是否会产生大量工作负载?如果是这样的话,你可能应该把它移到一个后台工作者那里..不,完全是被动代码。
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);
}
}