9

如何在 C# 中创建一个强制应用程序在指定时间关闭的计时器?我有这样的事情:

void  myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    if (++counter == 120)
        this.Close();
}

但在这种情况下,应用程序将在计时器运行后 120 秒内关闭。我需要一个计时器,它会在例如 23:00:00 关闭应用程序。有什么建议么?

4

7 回答 7

9

您必须解决的第一个问题是 System.Timers.Timer 不起作用。它在线程池线程上运行 Elapsed 事件处理程序,这样的线程不能调用 Form 或 Window 的 Close 方法。简单的解决方法是使用同步计时器,System.Windows.Forms.Timer 或 DispatcherTimer,从问题中不清楚哪个适用。

您唯一需要做的另一件事是计算计时器的 Interval 属性值。这是相当简单的 DateTime 算法。如果您总是希望窗口在晚上 11 点关闭,请编写如下代码:

    public Form1() {
        InitializeComponent();
        DateTime now = DateTime.Now;  // avoid race
        DateTime when = new DateTime(now.Year, now.Month, now.Day, 23, 0, 0);
        if (now > when) when = when.AddDays(1);
        timer1.Interval = (int)((when - now).TotalMilliseconds);
        timer1.Start();
    }
    private void timer1_Tick(object sender, EventArgs e) {
        this.Close();
    }
于 2012-11-29T13:35:57.843 回答
5

我假设您在这里谈论的是 Windows 窗体。那么这可能会起作用(编辑更改了this.Invoke使用的代码,因为我们在这里谈论的是多线程计时器):

void  myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{
    if (DateTime.Now.Hour >= 23)
        this.Invoke((Action)delegate() { Close(); });
}

如果您切换到使用 Windows 窗体Timer,则此代码将按预期工作:

void  myTimer_Elapsed(object sender, EventArgs e) 
{
    if (DateTime.Now.Hour >= 23)
        Close();
}
于 2012-11-29T13:07:35.063 回答
5

如果我理解您的要求,让计时器每秒检查一次时间似乎有点浪费,您可以在其中执行以下操作:

void Main()
{
    //If the calling context is important (for example in GUI applications)
    //you'd might want to save the Synchronization Context 
    //for example: context = SynchronizationContext.Current 
    //and use if in the lambda below e.g. s => context.Post(s => this.Close(), null)

    var timer = new System.Threading.Timer(
                s => this.Close(), null, CalcMsToHour(23, 00, 00), Timeout.Infinite);
}

int CalcMsToHour(int hour, int minute, int second)
{
    var now = DateTime.Now;
    var due = new DateTime(now.Year, now.Month, now.Day, hour, minute, second);
    if (now > due)
        due.AddDays(1);
    var ms =  (due - now).TotalMilliseconds;
    return (int)ms;
}
于 2012-11-29T13:26:54.290 回答
3

您可能想要获取当前系统时间。然后,查看当前时间是否与您希望应用程序关闭的时间相匹配。这可以使用DateTime表示时间的瞬间来完成。

例子

public Form1()
{
    InitializeComponent();
    Timer timer1 = new Timer(); //Initialize a new Timer of name timer1
    timer1.Tick += new EventHandler(timer1_Tick); //Link the Tick event with timer1_Tick
    timer1.Start(); //Start the timer
}

private void timer1_Tick(object sender, EventArgs e)
{
    if (DateTime.Now.Hour == 23 && DateTime.Now.Minute == 00 && DateTime.Now.Second == 00) //Continue if the current time is 23:00:00
    {
        Application.Exit(); //Close the whole application
        //this.Close(); //Close this form only
    }
}

谢谢,
我希望你觉得这有帮助:)

于 2012-11-29T13:12:10.023 回答
2
void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    if (DateTime.Now.Hour >= 23)
    {
        this.Close();
    }
}
于 2012-11-29T13:08:09.773 回答
2
Task.Delay(9000).ContinueWith(_ =>
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                    this.Close();
                }));
            }
            );
于 2016-05-12T04:44:57.847 回答
0

设置您的计时器以像现在一样检查每一秒,但将内容交换为:

void  myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
  if (DateTime.Now.Hour == 23)
    this.Close();
}

这将确保当计时器运行并且时钟为 23:xx 时,应用程序将关闭。

于 2012-11-29T13:07:45.313 回答