I want to execute a method every hour on the hour. I wrote some code,but it is not enough for my aim. Below code is working every 60 minutes.
public void Start()
{
System.Threading.Timer timerTemaUserBilgileri = new System.Threading.Timer(new System.Threading.TimerCallback(RunTakip), null, tmrTemaUserBilgileri, 0);
}
public void RunTakip(object temauserID)
{
try
{
string objID = "6143566557387";
EssentialMethod(objID);
TimeSpan span = DateTime.Now.Subtract(lastRunTime);
if (span.Minutes > 60)
{
tmrTemaUserBilgileri = 1 * 1000;
timerTemaUserBilgileri.Change(tmrTemaUserBilgileri, 0);
}
else
{
tmrTemaUserBilgileri = (60 - span.Minutes) * 60 * 1000;
timerTemaUserBilgileri.Change(tmrTemaUserBilgileri, 0);
}
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
}
catch (Exception ex)
{
timerTemaUserBilgileri.Change(30 * 60 * 1000, 0);
Utils.LogYaz(ex.Message.ToString());
}
}
public void EssentialMethod(objec obj)
{
//some code
lastRunTime = DateTime.Now;
//send lastruntime to sql
}
If you want your code to be executed every 60 minutes:
aTimer = new System.Timers.Timer(60 * 60 * 1000); //one hour in milliseconds
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Start();
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//Do the stuff you want to be done every hour;
}
if you want your code to be executed every hour (i.e. 1:00, 2:00, 3:00) you can create a timer with some small interval (let's say a second, depends on precision you need) and inside that timer event check if an hour has passed
aTimer = new System.Timers.Timer(1000); //One second, (use less to add precision, use more to consume less processor time
int lastHour = DateTime.Now.Hour;
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Start();
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
if(lastHour < DateTime.Now.Hour || (lastHour == 23 && DateTime.Now.Hour == 0))
{
lastHour = DateTime.Now.Hour;
YourImportantMethod(); // Call The method with your important staff..
}
}
I agree with Señor Salt that the chron job should be the first choice. However, the OP asked for every hour on the hour from c#. To do that, I set up the first timed event to fire on the hour:
int MilliSecondsLeftTilTheHour()
{
int interval;
int minutesRemaining = 59 - DateTime.Now.Minute;
int secondsRemaining = 59 - DateTime.Now.Second;
interval = ((minutesRemaining * 60) + secondsRemaining) * 1000;
// If we happen to be exactly on the hour...
if (interval == 0)
{
interval = 60 * 60 * 1000;
}
return interval;
}
Timer timer = new Timer();
timer.Tick += timer_Tick;
timer.Enabled = true;
timer.Interval = MilliSecondsLeftTilTheHour();
The problem now is that if the above timer.Interval happens to be 45 minutes and 32 seconds, then the timer will continue firing every 45:32 not just the first time. So, inside the timer_Tick method, you have to readjust the timer.Interval to one hour.
void timer_Tick(object sender, EventArgs e)
{
// The Interval could be hard wired here to 60 * 60 * 1000 but on clock
// resets and if the job ever goes longer than an hour, why not
// recalculate once an hour to get back on track.
timer.Interval = MilliSecondsLeftTilTheHour();
DoYourThing();
}
Just a small comment based on /Anarion's solution that I couldn't fit into a comment.
you can create a timer with some small interval (let's say a second, depends on precision you need)
You don't need it to go with any precision at all, you're thinking "how do I check this hour is the hour I want to fire". You could alternatively think "How do I check the next hour is the hour I want to fire" - once you think like that you realise you don't need any precision at all, just tick once an hour, and set a thread for the next hour. If you tick once an hour you know you'll be at some point before the next hour.
Dim dueTime As New DateTime(Date.Today.Year, Date.Today.Month, Date.Today.Day, DateTime.Now.Hour + 1, 0, 0)
Dim timeRemaining As TimeSpan = dueTime.Subtract(DateTime.Now)
t = New System.Threading.Timer(New System.Threading.TimerCallback(AddressOf Method), Nothing, CType(timeRemaining.TotalMilliseconds, Integer), System.Threading.Timeout.Infinite)
How about something simpler? Use a one-minute timer to check the hour:
public partial class Form1 : Form
{
int hour;
public Form1()
{
InitializeComponent();
if(RunOnStartUp)
hour = -1;
else
hour = DateTime.Now.Hour;
}
private void timer1_Tick(object sender, EventArgs e)
{
// once per minute:
if(DateTime.Now.Hour != hour)
{
hour = DateTime.Now.Hour;
DailyTask();
}
}
private DailyTask()
{
// do something
}
}
Use a Cron Job on the server to call a function at the specified interval
Heres a link http://www.thesitewizard.com/general/set-cron-job.shtml
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With