在.net闹钟应用程序闹钟、应用程序、net

2023-09-02 01:33:11 作者:涉世渡河人

我真的不写一个闹钟应用程序,但它有助于说明我的问题。

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.