C# 关闭应用程序的计时器

C# 关闭应用程序的计时器,c#,timer,C#,Timer,如何在C#中创建一个计时器,强制应用程序在指定时间关闭?我有这样的想法: void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (++counter == 120) this.Close(); } void Main() { //If the calling context is important (for example in GUI applications)

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

void  myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    if (++counter == 120)
        this.Close();
}
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;
}
    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();
    }

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

我想你在这里谈论的是Windows窗体。然后这可能会起作用(EDIT更改了代码,因此使用了
this.Invoke
,正如我们在这里讨论的多线程计时器):

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

void  myTimer_Elapsed(object sender, EventArgs e) 
{
    if (DateTime.Now.Hour >= 23)
        Close();
}

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

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

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

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

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

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
    }
}
谢谢,

我希望这对您有所帮助:)

如果我理解您的要求,让计时器每秒检查时间似乎有点浪费,您可以这样做:

void  myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    if (++counter == 120)
        this.Close();
}
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;
}
    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();
    }

您必须解决的第一个问题是System.Timers.Timer无法工作。它在线程池线程上运行已用事件处理程序,这样的线程无法调用窗体或窗口的Close方法。简单的解决方法是使用同步计时器,可以是System.Windows.Forms.timer,也可以是Dispatchermer,但问题是不清楚该使用哪个

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

void  myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    if (++counter == 120)
        this.Close();
}
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;
}
    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();
    }


你是说23小时后?或在时钟滴答到23后,记录应用程序启动的时间。确定应用程序应在何时关闭。在一个每5分钟检查一次的计时器线程中,检查它是什么时间,这将使您接近您需要的时间。在你走到这一步之后,你可以问一些关于你的代码的具体问题。我不会提供exmaple,因为您甚至没有尝试过。他想在晚上11点关闭程序,而不是在程序运行23小时后关闭。@ThorstenDittmar-ohh than我错了。我刚刚删除了我的答案大多数答案都没有效率,这会每隔一段时间运行一次计时器,并白白浪费CPU时间,看看我的答案。这不是很有效,它会每隔一段时间运行一次计时器,并且会花费cpu时间,但这是最简单的基于OP的代码。另外,我让您将每分钟执行我的代码(在任何给定的计时器间隔<1小时的情况下都能可靠地工作)所损失的时间量与您的解决方案消耗的脑细胞数量进行比较:-DIt不仅效率低下,而且无法工作。不能在工作线程中调用Close()方法。导致的异常被默默地吞没,窗口根本不会关闭。哦,我没有注意到,正如OP所说的,他提供的代码示例工作正常。我会解决的。我觉得每个人都在谈论“效率”很有趣。如果我每次都从网络服务器上下载一个文件,那么我就在谈论效率——但是,来吧……谢谢你,这个答案最适合我的问题,因为我需要所有时间:设置小时、分钟和秒。谢谢你,这就是我要找的。。只需调用计时器一次)那么,你试过这个代码吗?窗户真的关上了吗?即使在不同线程的上下文中调用了
this.Close()
。@Thorsten Dittmar-yup,它仍然有效。其他一些示例与调用它的线程有关,存在这样的异常。@Thorsten Dittmar,因为标记并不意味着WPF或Winforms,所以我不能假设存在
同步上下文(理论上
Close
可以做任何事)OP没有指定如果程序在2300到午夜之间启动应该发生什么,但是也许您应该添加
if(now>when)when。AddDays(1)
替换了我的解决方案,该解决方案基于ohadsc答案,使用您的答案。谢谢。在答案中添加一些解释,说明此答案如何帮助OP解决当前问题