Timer Run Every 5Th Minute

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



Leave a reply



Submit