How to call a method daily, at a specific time, in C #?

I searched for SO and found answers about Quartz.net. But that seems too big for my project. I want an equivalent solution, but simpler and (at best) in-code (no external library required). How can I call a method daily, at a specific time?

I need to add some information about this:

  • The easiest (and ugliest) way to do this is to check the time every second / minute and call the method at the right time

I want a more efficient way to do this, there is no need to constantly check the time, and I have control over whether the task is completed. If the method fails (due to any problems), the program must know to write to register / send e-mail. This is why I need to call a method, not schedule a task.

I found this solution calling a method at a fixed time in Java to Java. Is there a similar way in C #?

EDIT: I did it. I added a parameter to void Main () and created a bat (scheduled by the Windows Task Scheduler) to run a program with this parameter. The program starts, executes the task, and then exits. If the job fails, he is able to record a log and send email. This approach fits my requirements well :)

+68
methods c # scheduled-tasks winforms
Jul 14 '10 at 4:14
source share
14 answers

This is really all you need!

Update: if you want to do this inside your application, you have several options:

  • in a Windows Forms application , you can click on Application.Idle and check if you want "I reached the time to call your method. This method is called only when your application is not busy with other things. A quick check to see if it is reached your target time, do not click too hard on your application, I think ...
  • ASP.NET web application has methods to "simulate" sending scheduled events - check out this CodeProject article
  • and, of course, you can just simply "collapse your own" in any .NET application - see this CodeProject article for a sample implementation

Update # 2 : if you want to check every 60 minutes, you can create a timer that wakes up every 60 minutes, and if the time comes, it calls the method.

Something like that:

 using System.Timers; const double interval60Minutes = 60 * 60 * 1000; // milliseconds to one hour Timer checkForTime = new Timer(interval60Minutes); checkForTime.Elapsed += new ElapsedEventHandler(checkForTime_Elapsed); checkForTime.Enabled = true; 

and then in the event handler:

 void checkForTime_Elapsed(object sender, ElapsedEventArgs e) { if (timeIsReady()) { SendEmail(); } } 
+71
Jul 14 '10 at 4:16
source share

Whenever I create applications that require such features, I always use the Windows Task Scheduler using the simple .NET library that I found.

Please see my answer to a similar question for sample code and additional explanations.

+9
Jul 14 '10 at 6:09
source share

As others have said, you can use the console application to run on schedule. What others have not said is that you can run this application through the EventWaitHandle, which you expect in your main application.

Console Application:

 class Program { static void Main(string[] args) { EventWaitHandle handle = new EventWaitHandle(true, EventResetMode.ManualReset, "GoodMutexName"); handle.Set(); } } 

Main application:

 private void Form1_Load(object sender, EventArgs e) { // Background thread, will die with application ThreadPool.QueueUserWorkItem((dumby) => EmailWait()); } private void EmailWait() { EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset, "GoodMutexName"); while (true) { handle.WaitOne(); SendEmail(); handle.Reset(); } } 
+8
Jul 14 '10 at 6:02
source share

I created a simple scheduler that is easy to use and you do not need to use an external library. TaskScheduler is a singleton that stores links to timers, so timers will not collect garbage, it can schedule several tasks. You can set the first run (hour and minute) if at the time of scheduling this time runs out when planning begins the next day at that time. But easy to customize the code.

Scheduling a new task is so simple. Example: at 11:52 the first task is for every 15 seconds, the second example is for every 5 seconds. For daily execution, set 24 to parameter 3.

 TaskScheduler.Instance.ScheduleTask(11, 52, 0.00417, () => { Debug.WriteLine("task1: " + DateTime.Now); //here write the code that you want to schedule }); TaskScheduler.Instance.ScheduleTask(11, 52, 0.00139, () => { Debug.WriteLine("task2: " + DateTime.Now); //here write the code that you want to schedule }); 

My debug window:

 task2: 07.06.2017 11:52:00 task1: 07.06.2017 11:52:00 task2: 07.06.2017 11:52:05 task2: 07.06.2017 11:52:10 task1: 07.06.2017 11:52:15 task2: 07.06.2017 11:52:15 task2: 07.06.2017 11:52:20 task2: 07.06.2017 11:52:25 ... 

Just add this class to your project:

 public class TaskScheduler { private static TaskScheduler _instance; private List<Timer> timers = new List<Timer>(); private TaskScheduler() { } public static TaskScheduler Instance => _instance ?? (_instance = new TaskScheduler()); public void ScheduleTask(int hour, int min, double intervalInHour, Action task) { DateTime now = DateTime.Now; DateTime firstRun = new DateTime(now.Year, now.Month, now.Day, hour, min, 0, 0); if (now > firstRun) { firstRun = firstRun.AddDays(1); } TimeSpan timeToGo = firstRun - now; if (timeToGo <= TimeSpan.Zero) { timeToGo = TimeSpan.Zero; } var timer = new Timer(x => { task.Invoke(); }, null, timeToGo, TimeSpan.FromHours(intervalInHour)); timers.Add(timer); } } 
+6
Jun 07 '17 at 10:45
source share

The best way that I know, and perhaps the easiest, is to use the Windows task scheduler to execute your code at a specific time of the day or run the application constantly and check a specific time of day or write a Windows service which does the same.

+4
Jul 14 '10 at 4:17
source share

I know this is deprecated, but what about this:

Create a timer to start at startup that calculates the time until the next run time. When you call the run time for the first time, cancel the first timer and start a new daily timer. change every hour every day or no matter what you want the frequency to be.

+4
Nov 17 '11 at 16:00
source share

If you want the executable to run, use the scheduled Windows tasks. I am going to assume (possibly erroneously) that you want the method to run in your current program.

Why not just start a thread that continuously stores the last date the method was called?

Wake up every minute (for example), and if the current time is more than the specified time and the last date is not the current date, call the method and then update the date.

+1
Jul 14 '10 at 4:18
source share

I recently wrote a C # application that had to be restarted daily. I understand this question is old, but I don’t think it hurts to add another possible solution. So I handled daily reboots at the specified time.

 public void RestartApp() { AppRestart = AppRestart.AddHours(5); AppRestart = AppRestart.AddMinutes(30); DateTime current = DateTime.Now; if (current > AppRestart) { AppRestart = AppRestart.AddDays(1); } TimeSpan UntilRestart = AppRestart - current; int MSUntilRestart = Convert.ToInt32(UntilRestart.TotalMilliseconds); tmrRestart.Interval = MSUntilRestart; tmrRestart.Elapsed += tmrRestart_Elapsed; tmrRestart.Start(); } 

To ensure that your timer is kept in scope, I recommend creating it outside the method using the System.Timers.Timer tmrRestart = new System.Timers.Timer() method. Place the RestartApp() method RestartApp() form load event. When the application starts, the values ​​for AppRestart will be set, if current greater than the restart time, we add 1 day to AppRestart to ensure that the restart occurs on time and that we do not receive an exception for a negative value in the timer. The tmrRestart_Elapsed event fires any code you need at the specified time. If your application restarts on its own, you do not have to stop the timer, but that will not hurt either. If the application does not restart, just call the RestartApp() method again and you will be fine.

+1
Oct 19 '16 at 13:14
source share

It may be just me, but it seemed that most of these answers were not complete or would not work correctly. I did something very quick and dirty. That being said, I'm not sure how good the idea is to do it this way, but it works great every time.

 while (true) { if(DateTime.Now.ToString("HH:mm") == "22:00") { //do something here //ExecuteFunctionTask(); //Make sure it doesn't execute twice by pausing 61 seconds. So that the time is past 2200 to 2201 Thread.Sleep(61000); } Thread.Sleep(10000); } 
+1
Dec 16 '16 at 21:40
source share

Here you can do it using TPL. No need to create / delete a timer, etc .:

 void ScheduleSomething() { var runAt = DateTime.Today + TimeSpan.FromHours(16); if (runAt <= DateTime.Now) { DoSomething(); } else { var delay = runAt - DateTime.Now; System.Threading.Tasks.Task.Delay(delay).ContinueWith(_ => DoSomething()); } } void DoSomething() { // do somethig } 
+1
Nov 28 '17 at 3:17
source share

Instead of setting a time to start every second every 60 minutes, you can calculate the remaining time and set the timer to half (or some other fraction) of this. Thus, you do not check the time so much, but also maintain a certain degree of accuracy, since the timer interval reduces the time it takes to approach the target time.

For example, if you want to do something in 60 minutes, the timers will be aproximatly:

30:00:00, 15:00:00, 07:30:00, 03:45:00, ..., 00:00:01, RUN!

I use the following code to automatically restart the service once a day. I use the thread because I found the timers unreliable for a long time, while it is more expensive in this example, it is the only thing that is created for this purpose, so it does not matter.

(converted from VB.NET)

 autoRestartThread = new System.Threading.Thread(autoRestartThreadRun); autoRestartThread.Start(); 

...

 private void autoRestartThreadRun() { try { DateTime nextRestart = DateAndTime.Today.Add(CurrentSettings.AutoRestartTime); if (nextRestart < DateAndTime.Now) { nextRestart = nextRestart.AddDays(1); } while (true) { if (nextRestart < DateAndTime.Now) { LogInfo("Auto Restarting Service"); Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = string.Format("/C net stop {0} && net start {0}", "\"My Service Name\""); p.StartInfo.LoadUserProfile = false; p.StartInfo.UseShellExecute = false; p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; p.StartInfo.CreateNoWindow = true; p.Start(); } else { dynamic sleepMs = Convert.ToInt32(Math.Max(1000, nextRestart.Subtract(DateAndTime.Now).TotalMilliseconds / 2)); System.Threading.Thread.Sleep(sleepMs); } } } catch (ThreadAbortException taex) { } catch (Exception ex) { LogError(ex); } } 

Note. I set the minimum interval to 1000 ms, it may not be studied, reduced or deleted depending on the required accuracy.

Remember to also stop the thread / timer when closing the application.

0
Dec 18 '15 at 11:11
source share

I have a simple approach to this. This creates a delay of 1 minute before the action occurs. You can also add seconds to do Thread.Sleep (); in short.

 private void DoSomething(int aHour, int aMinute) { bool running = true; while (running) { Thread.Sleep(1); if (DateTime.Now.Hour == aHour && DateTime.Now.Minute == aMinute) { Thread.Sleep(60 * 1000); //Wait a minute to make the if-statement false //Do Stuff } } } 
0
Jan 05 '17 at 10:33
source share

24 hours

 var DailyTime = "16:59:00"; var timeParts = DailyTime.Split(new char[1] { ':' }); var dateNow = DateTime.Now; var date = new DateTime(dateNow.Year, dateNow.Month, dateNow.Day, int.Parse(timeParts[0]), int.Parse(timeParts[1]), int.Parse(timeParts[2])); TimeSpan ts; if (date > dateNow) ts = date - dateNow; else { date = date.AddDays(1); ts = date - dateNow; } //waits certan time and run the code Task.Delay(ts).ContinueWith((x) => OnTimer()); public void OnTimer() { ViewBag.ErrorMessage = "EROOROOROROOROR"; } 
0
Jun 26 '18 at 11:33
source share

I found this very useful:

 using System; using System.Timers; namespace ScheduleTimer { class Program { static Timer timer; static void Main(string[] args) { schedule_Timer(); Console.ReadLine(); } static void schedule_Timer() { Console.WriteLine("### Timer Started ###"); DateTime nowTime = DateTime.Now; DateTime scheduledTime = new DateTime(nowTime.Year, nowTime.Month, nowTime.Day, 8, 42, 0, 0); //Specify your scheduled time HH,MM,SS [8am and 42 minutes] if (nowTime > scheduledTime) { scheduledTime = scheduledTime.AddDays(1); } double tickTime = (double)(scheduledTime - DateTime.Now).TotalMilliseconds; timer = new Timer(tickTime); timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Start(); } static void timer_Elapsed(object sender, ElapsedEventArgs e) { Console.WriteLine("### Timer Stopped ### \n"); timer.Stop(); Console.WriteLine("### Scheduled Task Started ### \n\n"); Console.WriteLine("Hello World!!! - Performing scheduled task\n"); Console.WriteLine("### Task Finished ### \n\n"); schedule_Timer(); } } } 
0
Apr 15 '19 at 15:12
source share



All Articles