如何在C#中特定时间生成警报?

28

我怎样才能在特定时间生成一个事件?例如,假设我想要在早上8点生成一个提醒,告诉我现在是早上8点(或者在任何给定的时间告诉我当前时间的事件)。

4个回答

47

使用 System.Threading.Timer 类:

var dt = ... // next 8:00 AM from now
var timer = new Timer(callback, null, dt - DateTime.Now, TimeSpan.FromHours(24));

callback委托将在下一次为早上8点时被调用,并且每24小时调用一次。

请参见此SO问题以了解如何计算下一个早上8点的出现时间。


4
我知道跟随该链接会提到它,但可能需要澄清一下,那是System.Threading.Timer而不是System.Windows.Forms.Timer。 - McAden
1
如果我现在提供最后的8.00,这样会起作用吗?所以会给出一个负数? - Jaanus
@Jaanus 不,我刚试了一下,它会抛出一个异常。如果 dt < DateTime.Now,则执行 dt.AddDays(1)。 - Brian Tacker
1
在实践中这似乎不太可靠。我使用了Threading命名空间中的计时器类实现了一些代码。它被设计用来在特定时间(如午夜)滚动日志文件。在我们的案例中,我们注意到在生产环境中,有时滚动操作会在午夜之前或之后略微发生。我猜大多数情况下这已经足够好了,但是似乎执行时间有时候会稍微有所差别。 - Mark W

9
深入阐述dtb的回答,这是我实现它的方式。
  private void Form1_Load(object sender, EventArgs e)
    {
        System.Threading.TimerCallback callback = new TimerCallback(ProcessTimerEvent);

        //first occurrence at
        var dt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 10, 0, 0);

        if (DateTime.Now < dt)
        {
            var timer = new System.Threading.Timer(callback, null, 
                                               //other occurrences every 24 hours
                            dt - DateTime.Now, TimeSpan.FromHours(24));
        }

    }

    private void ProcessTimerEvent(object obj)
    {
        MessageBox.Show("Hi Its Time");
    }

1

警报是否必须由您的程序生成?另一种方法是使用计划任务(在Windows中)来生成警报。您可能需要编写一个小程序,从主应用程序的数据文件等收集任何信息。

使用此方法有几个主要好处:

  1. 您不必编写任何支持该功能的代码。您可以利用操作系统中内置的功能。该示例适用于Windows,但其他操作系统也具有相同的功能。您可以将开发和支持工作集中在自己的代码上。
  2. 您的主应用程序不必运行即可触发任务。

0
private void Run_Timer()
    {
        DateTime tday = new DateTime();
        tday = DateTime.Today;
        TimeSpan Start_Time = new TimeSpan(8,15,0);
        DateTime Starter = tday + Start_Time;
        Start_Time = new TimeSpan(20, 15, 0);
        DateTime Ender = tday + Start_Time;
        for (int i = 0; i <= 23; i++)
        {
            Start_Time = new TimeSpan(i, 15, 0);
            tday += Start_Time;
            if (((tday - DateTime.Now).TotalMilliseconds > 0) && (tday >= Starter) && (tday <= Ender))
            {
                Time_To_Look = tday;
                timer1.Interval = Convert.ToInt32((tday - DateTime.Now).TotalMilliseconds);
                timer1.Start();
                MessageBox.Show(Time_To_Look.ToString());
                break;
            }
        }
    }

我们可以使用这个函数来获取计时器运行的时间或将其更改为在特定时间运行 :D

@dtb的解决方案显然更好。 - albertein
3
但很明显你没有理解一个人问问题的时候最好先了解自己的问题。我同意他给我一个特定时间格式的样本,但是我必须让它在一些条件下运行,而不是静态地在特定时间运行。我的代码大部分工作都是为了运行那个循环,并设置下一个计时器停止的时间。如果你能看出这一点,重要的不是那段代码的行数。 - Mobin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接