Timer run every 5th minute
The answer posted six years ago is useful. However, IMHO with modern C# it is now better to use the Task
-based API with async
and await
. Also, I differ a little on the specifics of the implementation, such as how to manage the delay computation and how to round the current time to the next five minute interval.
First, let's assume the sendRequest()
method returns void
and has no parameters. Then, let's assume that the basic requirement is to run it roughly every five minutes (i.e. it's not that important that it run exactly on five-minute divisions of the hour). Then that can be implemented very easily, like this:
async Task RunPeriodically(Action action, TimeSpan interval, CancellationToken token)
{
while (true)
{
action();
await Task.Delay(interval, token);
}
}
It can be called like this:
CancellationTokenSource tokenSource = new CancellationTokenSource();
Task timerTask = RunPeriodically(sendRequest, TimeSpan.FromMinutes(5), tokenSource.Token);
When tokenSource.Cancel()
is called, the loop will be interrupted by the TaskCanceledException
thrown at the await Task.Delay(...)
statement. Otherwise, the sendRequest()
method will be called every five minutes (with it being called immediately when the RunPeriodically()
method is called…you can reorder the statements in the loop if you want it to wait the first time too).
That's the simplest version. If instead you do want to perform the action exactly on five minute intervals, you can do something similar, but compute the next run time and delay for an appropriate amount of time. For example:
// private field somewhere appropriate; it would probably be best to put
// this logic into a reusable class.
DateTime _nextRunTime;
async Task RunPeriodically(Action action,
DateTime startTime, TimeSpan interval, CancellationToken token)
{
_nextRunTime = startTime;
while (true)
{
TimeSpan delay = _nextRunTime - DateTime.UtcNow;
if (delay > TimeSpan.Zero)
{
await Task.Delay(delay, token);
}
action();
_nextRunTime += interval;
}
}
Called like this:
CancellationTokenSource tokenSource = new CancellationTokenSource();
DateTime startTime = RoundCurrentToNextFiveMinutes();
Task timerTask = RunPeriodically(sendRequest,
startTime, TimeSpan.FromMinutes(5), tokenSource.Token);
Where the helper method RoundCurrentToNextFiveMinutes()
looks like this:
DateTime RoundCurrentToNextFiveMinutes()
{
DateTime now = DateTime.UtcNow,
result = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
return result.AddMinutes(((now.Minute / 5) + 1) * 5);
}
In either example, the timerTask
object can be used to monitor the state of the loop. In most cases, it's probably not needed. But if you want to be able to, e.g. await
until some other part of the code cancels the loop, this object is what you'd use.
Note that the Task.Delay()
method does use a timer in its implementation. The above is not suggested for the purpose of avoiding the use of a timer, but rather to show an implementation of the original goal using the modern C# async
/await
features. This version will mesh more cleanly with other code that is already using async
/await
.
Run a function at the start of every round 5 minute interval
You could use a threading.Timer
. You have to do some math to calculate the next run time. datetime
has a handy replace
method for that.
from datetime import datetime, timedelta
from threading import Timer
from time import sleep
import random
def schedule_next_run():
sleep_time = get_sleep_time()
t = Timer(sleep_time, do_work)
t.daemon = True
t.start()
print(f'sleeping for {sleep_time} seconds')
def get_sleep_time():
now = datetime.now()
last_run_time = now.replace(minute=now.minute // 5 * 5, second=0, microsecond=0)
next_run_time = last_run_time + timedelta(minutes=5)
return (next_run_time - now).total_seconds()
def do_work():
now = datetime.now()
print('Doing some work at', now)
sleep(random.uniform(0, 29))
print('Work complete. Scheduling next run.')
schedule_next_run()
print('Starting work schedule')
schedule_next_run()
input('Doing work every 5 minutes. Press enter to exit:\n')
On my system, the function fires within a half millisecond of the target time
Note that the time calculation rounds down and then adds a timedelta
to carefully wrap around the end of each hour. You would want to ponder how this will behave around daylight savings changes.
Suggestion: move all this logic to a class to clean it up.
JQuery run every 5 minutes past the hour 5,10,15...55
Using setInterval
to call the function every second.
Then using a filter by current time having a minute divisible by 5 and seconds zero.
var timer = 0;timer = setInterval(function(){ var currentdate = new Date(); if(currentdate.getMinutes() % 5 == 0 && currentdate.getSeconds() == 0) { console.log("Alarm"); }}, 1000);//to stop: clearInterval(timer);
Checking setInterval every 5 minutes on the 0 second
You should find out what's the time to your next rounded 5 min. like this:
const FIVE_MIN = 1000 * 60 * 5;
function waitAndDoSomething() {
const msToNextRounded5Min = FIVE_MIN - (Date.now() % FIVE_MIN);
console.log(`Waiting ${msToNextRounded5Min}ms. to next rounded 5Min.`);
setTimeout(() => {
console.log('It is now rounded 5 min');
waitAndDoSomething();
}, msToNextRounded5Min);
}
waitAndDoSomething();
Python does something every 5 minutes
UPDATE:
Just wanted to remove the possibility of recursion error, so I have rewritten the code:
from threading import Thread
from time import sleep
import datetime
def check_api():
# ... your code here ...
pass
def schedule_api():
while datetime.datetime.now().minute % 5 != 0:
sleep(1)
check_api()
while True:
sleep(300)
check_api()
thread = Thread(target=schedule_api)
thread.start()
Also if you want your thread to quit when the main program exits you could set daemon as True on the thread like:
thread.daemon = True
But this does not enforce a clean termination of this thread so you could also try this approach below:
# ...
RUNNING = True
# ...
thread = Thread(target=schedule_api)
thread.start()
#...
def main():
# ... all main code ...
pass
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
RUNNING = False
You can use the following code:
import threading
def check_api():
pass
timer_thread = threading.Timer(300, check_api)
timer_thread.start()
# call timer_thread.cancel() when you need it to stop
This will call your check_api
function every 5 minutes and will not block your main code's execution.
as mentioned by @scotyy3785 the above code will only run once but I realize what you want and have written the code for it:
from threading import Thread
from time import sleep
import datetime
def check_api():
# ... your code here ...
pass
def caller(callback_func, first=True):
if first:
while not datetime.datetime.now().minute % 5 == 0:
sleep(1)
callback_func()
sleep(300)
caller(callback_func, False)
thread = Thread(target=caller, args=(check_api,))
thread.start()
# you'll have to handle the still running thread on exit
The above code will call check_api
at minutes like 00, 05, 10, 15...
Related Topics
Recursive Linq Query: Select Item and All Children with Subchildren
How to Detect Iis Version Using C#
C#: Throwing Custom Exception Best Practices
Logoff Interactive Users in Windows from a Service
Windows Form Application Exception
How to Evaluate Expression Whilst Debugging
How to Fix Ill-Formed HTML with HTML Agility Pack
Gridview with Fixed Header and Full Page Width Grid
Error 0X80005000 and Directoryservices
Directory.Getcurrentdirectory() Not Working on Linux
Retrieve an Object from Entityframework Without One Field
How to Set Datagridview Textbox Column to Multi-Line
Dotnet.Highcharts: Cost Not Plotted Against the Correct Date
How to Pass Strings from C# to C++ (And from C++ to C#) Using Dllimport
Detecting Symbolic Links and Pipes in Mono
How to Programmatically Apply a CSS Class to an ASP.NET Control