prvit
prvit

Reputation: 966

Timer to close the application

How to make a timer which forces the application to close at a specified time in C#? I have something like this:

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

But in this case, the application will be closed in 120 sec after the timer has ran. And I need a timer, which will close the application for example at 23:00:00. Any suggestions?

Upvotes: 10

Views: 24448

Answers (7)

shaiju mathew
shaiju mathew

Reputation: 443

Task.Delay(9000).ContinueWith(_ =>
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                    this.Close();
                }));
            }
            );

Upvotes: 3

Hans Passant
Hans Passant

Reputation: 941515

The first problem you have to fix is that a System.Timers.Timer won't work. It runs the Elapsed event handler on a thread-pool thread, such a thread cannot call the Close method of a Form or Window. The simple workaround is to use a synchronous timer, either a System.Windows.Forms.Timer or a DispatcherTimer, it isn't clear from the question which one applies.

The only other thing you have to do is to calculate the Interval property value for the timer. That's fairly straight-forward DateTime arithmetic. If you always want the window to close at, say, 11 o'clock in the evening then write code like this:

    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();
    }

Upvotes: 9

Ohad Schneider
Ohad Schneider

Reputation: 38112

If I understand your request, it seems a little wasteful to have a timer check the time every second, where you can do something like this:

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;
}

Upvotes: 5

Thorsten Dittmar
Thorsten Dittmar

Reputation: 56697

I'm assuming you're talking about Windows Forms here. Then this might work (EDIT Changed the code so this.Invoke is used, as we're talking about a multi-threaded timer here):

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

If you switch to using the Windows Forms Timer, then this code will work as expected:

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

Upvotes: 5

Gregor Primar
Gregor Primar

Reputation: 6805

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

Upvotes: 3

Picrofo Software
Picrofo Software

Reputation: 5571

You may want to get the current system time. Then, see if the current time matches the time you would like your application to close at. This can be done using DateTime which represents an instant in time.

Example

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

Thanks,
I hope you find this helpful :)

Upvotes: 3

Øyvind Bråthen
Øyvind Bråthen

Reputation: 60694

Set up your timer to check every second like now, but swap the contents with:

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

This will make sure that when the timer run and the clock is 23:xx, then the application will shut down.

Upvotes: 0

Related Questions