I am working on a Console application that must perform some actions at certain times of the day (I clarify that it is not a service because I need the execution of processes)
The thing is that I have to start an application at a certain time and close it at another.
Searching, I found an answer on SO in English that does something similar to what I am looking for but with a single execution, I tried to modify the snippet a bit as follows:
private void SetUpTimer(TimeSpan alertTime, DateTime current, Action<TimeSpan> delg)
{
TimeSpan timeToGo = alertTime - current.TimeOfDay;
if (timeToGo < TimeSpan.Zero)
{
return;//time already passed
}
this.timer = new System.Threading.Timer(x =>
{
delg(alertTime);
}, null, timeToGo, Timeout.InfiniteTimeSpan);
}
public void OpenProcess(TimeSpan alertTime)
{
Console.WriteLine("Ejecutado {0}",DateTime.Now);
SetUpTimer(alertTime, DateTime.Now.AddDays(1), OpenProcess);
}
and then I call it as follows
SetUpTimer(new TimeSpan(13, 44, 00), DateTime.Now, OpenProcess);
The first time it does it correctly, but the second time, the OpenProcess() function does not execute.
Where is my mistake?
Thank you!
In your code
timeToGo
, it marks the time remaining for your timer to run again and is defined as a subtraction of oneTimeStamp
(alertTime
) from another (current.TimeOfDay
).What happens when you call
SetUpTimer(alertTime, DateTime.Now.AddDays(1), OpenProcess);
from theOpenProcess
?What you use
AddDays
is irrelevant, since to calculate the time you useTimeOfDay
that does not take into account the date, and you also call it at the same time that the timer tick is supposed to jump, which actuallytimeToGo
gives a negative result, and logically it will not fire again the next day.I have already told you in a comment that it is better in my opinion to use a windows scheduled task for these tasks, but I will give you a solution if you insist on this path.
The solution is to use dates instead of TimeStamps for calculating the time remaining to fire the timer tick again, something like this:
To call it the first time, like this (if it's before the time you schedule it):
And
OpenProcess
it would be like this:I think the best way to do this is to implement the concept of Workers. You must have your Console application execute the required action instantly, without checking times or dates, and then schedule a recurring task through the operating system. In the case of Microsoft Windows, you can use Task Scheduler - Create a Basic Task - Declare how often the task will be executed - Action = Start a program, look for the Console application and Ready.