我真的不写一个闹钟应用程序,但它有助于说明我的问题。
I'm not really writing an alarm clock application, but it will help to illustrate my question.
让我们说,我在我的应用程序有一个方法,我想这个方法被称为在小时每隔一小时(如下午7:00,下午8点00分,下午九时00分等等)。我的可以的创建一个定时器并设置其间隔为3600000,但最终这将同步漂移与系统时钟。或者我的可以的使用,而()
循环与 Thread.sleep代码(N)
来定期检查系统时间,并调用方法时达到所需的时间,但我不喜欢这样或者( Thread.sleep代码(N)
是一个大$ C $ Ç气味对我来说)。
Let's say that I have a method in my application, and I want this method to be called every hour on the hour (e.g. at 7:00 PM, 8:00 PM, 9:00 PM etc.). I could create a Timer and set its Interval to 3600000, but eventually this would drift out of sync with the system clock. Or I could use a while()
loop with Thread.Sleep(n)
to periodically check the system time and call the method when the desired time is reached, but I don't like this either (Thread.Sleep(n)
is a big code smell for me).
我正在寻找的是.NET中的一些方法,让我传递了一个未来的DateTime对象和方法,委托或事件处理程序,但我一直没能找到任何这样的事情。我怀疑有Win32 API的,这是否在一个方法,但我一直没能找到,无论是。
What I'm looking for is some method in .Net that lets me pass in a future DateTime object and a method delegate or event handler, but I haven't been able to find any such thing. I suspect there's a method in the Win32 API that does this, but I haven't been able to find that, either.
或者,你可以用1秒的间隔创建一个计时器,并查看当前的时间每一秒,直到事件时间到达,如果是这样,你提高你的事件。
Or, you could create a timer with an interval of 1 second and check the current time every second until the event time is reached, if so, you raise your event.
您可以做一个简单的包装为:
You can make a simple wrapper for that :
public class AlarmClock
{
public AlarmClock(DateTime alarmTime)
{
this.alarmTime = alarmTime;
timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Interval = 1000;
timer.Start();
enabled = true;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(enabled && DateTime.Now > alarmTime)
{
enabled = false;
OnAlarm();
timer.Stop();
}
}
protected virtual void OnAlarm()
{
if(alarmEvent != null)
alarmEvent(this, EventArgs.Empty);
}
public event EventHandler Alarm
{
add { alarmEvent += value; }
remove { alarmEvent -= value; }
}
private EventHandler alarmEvent;
private Timer timer;
private DateTime alarmTime;
private bool enabled;
}
用法:
AlarmClock clock = new AlarmClock(someFutureTime);
clock.Alarm += (sender, e) => MessageBox.Show("Wake up!");
请注意code以上是非常粗略的,而不是线程安全的。
Please note the code above is very sketchy and not thread safe.