If I understand your question correctly then you want to do something, start a program in this case, at a specific time. While a Timer could be used it is going to be finicky. The problem is that timers are designed to trigger after a particular interval, not at a particular time. So if it is 10:30 now and you want to do something at midnight you'd need to calculate the interval that remains (midnight - 1030) and then set the timer to elapse at that point.
//This must be a field in your form, not a local variable so move the declaration out of function
Timer _timer;
TimeSpan _desiredStartTime = TimeSpan.FromHours(0);
TimeSpan GetRemainingTime ( )
{
return (DateTime.TimeOfDay - _desiredStartTime);
}
//Timer callback to see if it is time to start
void t_Tick ( )
{
//How much time is left? note that if desiredTime already elapsed then it is going to wrap
var remaining = GetRemainingTime();
if (remaining <= 0)
{
//Do starter work
};
}
Note that there are several Timer classes in NET. It appears you're using System.Windows.Forms.Timer. This timer relies on the UX thread to work. It is great if you need to update the UX but not recommended for other things. Futhermore it is stalled by the UX. So if your UX is busy doing something then the timer won't fire until after. Again, for UX stuff, this is fine.
Another issue with this timer is that once it is one then it remains on. In your case it seems like you should be stopping the timer once the program starts. You can do that by using the Enable
property or calling Stop
.
There are other timers available as well. Personally I might recommend you use the existing code you have to update the UX with the countdown. But the actual start code for the other program may do better to use a server timer which runs outside the UX and is more accurate. Provided you don't need to update the UX then this is the preferred approach. There are several of these but I'd probably just use System.Timers.Timer.
//Declare as a field in form
System.Timers.Timer _programTimer = new System.Timers.Timer();
//Code to start the timer
void StartTimer ()
{
_programTimer.Interval = GetRemainingTime();
//Thesse should only be set once, ideally at construction time of the timer
_programTimer.AutoRest = false; //Only run once
_programTimer.Elapsed += StartProgram; //Function to call to start the actual program
_programTimer.Start();
}
Finally note that Windows already has Task Scheduler built in that can ensure programs start at fixed intervals. This is ideally how you should handle this problem. Your program can show a counter but ultimately let Windows start the program for you. This ensure the program starts even if your UX app isn't running. Additionally Windows takes time change into account. The code given doesn't handle time changes done manually or during daylight savings time. You'll need to account for them as well. Manual time changes require that you hook into Window's time change event. DST can be handled by using DateTime (in UTC) or DateTimeOffset for calculating the remaining time because the date is needed for DST calculations. I believe the differences are correctly handled in these cases but honestly I've never bothered to look.