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.
void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.Hour >= 23)
{
this.Close();
}
}
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 :)
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();
}
Task.Delay(9000).ContinueWith(_ =>
{
this.Dispatcher.Invoke((Action)(() =>
{
this.Close();
}));
}
);
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();
}
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;
}