windows service timer set to weekly - c#

I have a windows service running with several timed functions:
_timer = new Timer(1 * 60 * 1000); // every 1 minute
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start();
_fbtimer = new System.Timers.Timer(48 * 60 * 60 * 1000);
_fbtimer.Elapsed += new System.Timers.ElapsedEventHandler(fbtimer_Elapsed);
_fbtimer.Start();
//Weekley Snapshot
_ventimer = new System.Timers.Timer(2 * 60 * 1000);
_ventimer.Elapsed += new System.Timers.ElapsedEventHandler(ventimer_Elapsed);
_ventimer.Start();
//Weekly Activity
_tevtimer = new System.Timers.Timer(2 * 60 * 1000);
_tevtimer.Elapsed += new System.Timers.ElapsedEventHandler(tevtimer_Elapsed);
_tevtimer.Start();
How do i set the timer to occur say once a week, or even better set it to a specific time on one day a week, without using quatrz/windows scheduler or a too different method.
Addition: this is how i am running a task everyday at 10
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//log.Info("Info - Check time");
DateTime startAt = DateTime.Today.AddHours(10);
if (_lastRun < startAt && DateTime.Now >= startAt)
{
_timer.Stop();
//Stuff
_lastRun = DateTime.Now;
_timer.Start();
}
}

without using quatrz/windows scheduler or a too different method.
Why reinvent the wheel, poorly? Anyway a weekly timer won't do much good. What if you code the timer to wait a week, and the machine reboots halfway the week for updates? The timer will start waiting a week again.
You'd better let it run at a small interval and check each time whether it's time to run the method you want. This way you can pre-calculate the 'event time' and check for it each time.

Related

If console application is running longer than expected then email to developer

I am having a console application written in c#, which is scheduled to run every 1 hr .
The application normally takes less than 10 min .
If the application is running more than 15 min I want to receive an email from the application with out breaking the code .
what is the best way to start with the minimum code .
You could set up a timer in your constructor
System.Timers.Timer aTimer = new System.Timers.Timer();
public static void Main()
{
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 1000 * 60 * 15; //1 second * 60 seconds in a minute * 15 minutes
aTimer.Enabled = true;
}
And then in the time elapsed event run your code which sends an email
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//Code which sends an email
aTimer.Enabled = false;
}
Make a timer that runs for 15 minutes.
After the period Ends, it should check for a condition (finished, yes no)
if not finished -> mail.

C# Timer Interval Every 24 Hours

I'm following a tutorial on how to create a Windows Service that will send automated emails on my web server. I've got the tutorial working, however, the example code executes the service every 60mins, instead, I'd like the service executed once a day, every 24 hours, say at 9am every morning.
Below is the sample code
private Timer scheduleTimer = null;
private DateTime lastRun;
private bool flag;
public StarEmailService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("EmailSource"))
{
System.Diagnostics.EventLog.CreateEventSource("EmailSource", "EmailLog");
}
eventLogEmail.Source = "EmailSource";
eventLogEmail.Log = "EmailLog";
scheduleTimer = new Timer();
scheduleTimer.Interval = 1 * 5 * 60 * 1000;
scheduleTimer.Elapsed += new ElapsedEventHandler(scheduleTimer_Elapsed);
}
protected override void OnStart(string[] args)
{
flag = true;
lastRun = DateTime.Now;
scheduleTimer.Start();
eventLogEmail.WriteEntry("Started");
}
protected void scheduleTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (flag == true)
{
ServiceEmailMethod();
lastRun = DateTime.Now;
flag = false;
}
else if (flag == false)
{
if (lastRun.Date < DateTime.Now.Date)
{
ServiceEmailMethod();
}
}
}
The line scheduleTimer.Interval = 1 * 5 * 60 * 1000; appears to be the code which sets the interval to 60mins, however, am unsure what would I need to amend this to in order to make it run every 24 hours at 9am?
Any advice would be appreciated.
Thanks.
You have couple of options:
Use Quartz .NET
Use Windows Schedule tasks
Don't rely on other timers as they will get out of sync in (near) future.
It is probably better to set your timer to smaller interval, and check the system time similar to your code does now. This code should send an email once a day on or after 9 am. The smaller your timer interval, the more accurate it will be to 9 am. For example, if you keep the timer interval at 60 minutes, the service will check the system time once an hour and the email will be sent between 9am and 10am. If you set the timer to 10 minutes, the service will check the system time once every tem minutes and send the email between 9:00 and 9:10am.
This method does not go out of sync over time, because it uses the system clock, not the timer interval to know when to fire.
Remove lastRun DateTime field and all references to it. Remove flag field and references. Add a DateTime field called nextRun:
private DateTime nextRun = DateTime.MinValue;
Add a function GetNextRun:
private static DateTime GetNextRun(DateTime lastRun)
{
var next = lastRun.AddDays(1);
return new DateTime(next.Year, next.Month, next.Day, 9, 0, 0);
}
Change ScheduleTimer Elapsed to:
protected void scheduleTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (DateTime.Now < nextRun) return;
nextRun = GetNextRun(DateTime.Now);
ServiceEmailMethod();
}

How to countdown in seconds from minutes using a countdown timer

Currently developing a simple windows phone 8.1 silverlight app with an implemented countdown time. I have it working where I can input a set amount of minutes and it countdowns fine but what I am wanting to happen is for a user to input an amount of minutes and to countdown in seconds from there, for example it is currently 10, 9, 8, 7, 6, 5 when 10 seconds is input.
What I want to happen is that the user inputs 5 and it counts down like so:
4:59
4:58
4:57
This is my current code:
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 1);
timer.Tick += timer_Tick;
basetime = Convert.ToInt32(tbxTime.Text);;
tbxTime.Text = basetime.ToString();
timer.Start();
}
void timer_Tick(object sender, object e)
{
basetime = basetime - 1;
tbxTime.Text = basetime.ToString();
if (basetime == 0)
{
timer.Stop();
}
You can keep most of your existing code if you just make basetime a TimeSpan instead of an int. It's easy to set its value from Minutes or Seconds via the appropriate static method.
var basetime = TimeSpan.FromMinutes(5);
Then you can subtract one second from it like this:
basetime -= TimeSpan.FromSeconds(1);
And display it like this:
tbxTime.Text = basetime.ToString(#"m\:ss");
Finally, comparing it to zero is also trivial:
if (basetime <= TimeSpan.Zero)
See Custom TimeSpan Format Strings for more display options.
I think you can just make use of suitable formatting of TimeSpan class (you will surely find many examples on SO). The easy example can look like this (I assume that you have a TextBox where you enter time and TextBlock which shows counter);
DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };
TimeSpan time;
public MainPage()
{
this.InitializeComponent();
timer.Tick += (sender, e) =>
{
time -= TimeSpan.FromSeconds(1);
if (time <= TimeSpan.Zero) timer.Stop();
myTextBlock.Text = time.ToString(#"mm\:ss");
};
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{ time = TimeSpan.FromMinutes(int.Parse((sender as TextBox).Text)); }
private void startBtn_Click(object sender, RoutedEventArgs e)
{ timer.Start(); }
Note that this is a very simple example. You should also think if DispatcherTimer is a good idea - it works on dispatcher, so in case you have some big job running on main UI thread it may not count the time properly. In this case you may think of using different timer, for example System.Threading.Timer, this runs on separate thread, so you will have to update your UI through Dispatcher.

Exactly fire tick event on completion of hour in C# Timer

I want the tick event to fire every hour exactly on completion of the hour. For e.g. it should tick on 8 am then on 9 am then on 10 am etc.
It's simple that I need to set the Interval to 3600000.
The problem here is how should I identify when should I start the timer?
I'm creating a tool which will run in system tray from the time when user will log on.
Please don't create a program that does nothing but waste memory. That's what Windows' Task Scheduler is for. Run your program every hour from such a task.
http://msdn.microsoft.com/en-us/library/aa384006%28v=VS.85%29.aspx
Here's a sample:
Go to Start->Programs->Accessories->Scheduled Tasks.
On the right side, click "Add Task..".
Select your executable.
Go to the Trigger tab.
Create Trigger with the following selection:
.
Run Daily
Start today at 8:00 am
Repeat every 1 Hour
I'm sorry that I can't provide any screenshots since I'm running the german version of Windows 7.
Maybe the following code is buggy, but the idea is like this:
public void InitTimer()
{
DateTime time = DateTime.Now;
int second = time.Second;
int minute = time.Minute;
if (second != 0)
{
minute = minute > 0 ? minute-- : 59;
}
if (minute == 0 && second == 0)
{
// DoAction: in this function also set your timer interval to 3600000
}
else
{
TimeSpan span = new TimeSpan(0, 60 - minute, 60 - second);
timer.Interval = (int) span.TotalMilliseconds - 100;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
}
void timer_Tick(object sender, EventArgs e)
{
timer.Interval = 3600000;
// DoAction
}
Per #smirkingman's suggestion, I removed 100 millisecond because of latency of project start-up and running time of the application:
timer.Interval = (int) span.TotalMilliseconds - 100;
I think it could be easier if you set up a timer every, let's say, minute, and this timer can check the system clock, when the desired time is less or equal than system time you can just run the actions (in this example with an error of 1 minute maximun)
You can improve it if you make the timer interval dinamyc, for example if you check the time and is still half an hour left you can set the interval for 15 minutes, nex time you reduce it to 5 minutoes and so on until you are checking the clock once a second, for examlpe.
HTH
Here's how I did this. The Tick event fires every 20 seconds. Simply change the minutes == "xxx" to whatever time you want the event to fire. If you need events spread out over hours, simply make the interval timer longer. Simple and effective.
private void timer1_Tick(object sender, EventArgs e)
{
DateTime Time = DateTime.Now;
int minutes = Time.Minute;
if (minutes == 00) //FIRE ON THE HOUR
{ DO THIS }
if (minutes == 15) //FIRE ON 1/4 HOUR
{ DO THIS }
if (minutes == 30) //FIRE ON 1/2 HOUR
{ DO THIS }
if (minutes == 45) //FIRE ON 3/4 HOUR
{ DO THIS }
}
Instead of firing the timer once an hour, maybe it would be more appropriate to fire the timer once a minute, and check to see if it's time yet.
The only problem with this is the worst case lag is 59 seconds. If you need it to fire exactly on the hour (at 10 am sharp), you may need to do some fiddling with the interval the first time so you line up.

Execute an operation every x seconds for y minutes in c#

I need to run a function every 5 seconds for 10 minutes.
I use a timer to run it for 5 secs, but how do I limit the timer to only 10 mins?
Just capture the time that you want to stop and end your timer from within the elapsed handler. Here's an example (note: I used a System.Threading.Timer timer. Select the appropriate timer for what you are doing. For example, you might be after a System.Windows.Forms.Timer if you are writing in Winforms.)
public class MyClass
{
System.Threading.Timer Timer;
System.DateTime StopTime;
public void Run()
{
StopTime = System.DateTime.Now.AddMinutes(10);
Timer = new System.Threading.Timer(TimerCallback, null, 0, 5000);
}
private void TimerCallback(object state)
{
if(System.DateTime.Now >= StopTime)
{
Timer.Dispose();
return;
}
// Do your work...
}
}
Have your timer loop something like this:
DateTime endTime = DateTime.Now.AddMinutes(10);
while(endTime < DateTime.Now)
{
// Process loop
}
Divide the Y minutes by the X interval to get how many times it needs to run. After that you just need to count how many times the function has been called.
In your case, 10 min = 600 seconds / 5 seconds = 120 calls needed. Just have a counter keep track of how many times your function has been called.
Timer.Stop() after 120 Ticks.
just use a DateTime variable to track when it should end and set that right before you start. The on your Elapsed event handler, check if the signal time is less than the end time. If it isn't, stop the timer.
You can calculate how times your function will be call, and create decrement counter, after elapsed which you unsubscribe from timer tick. Or you can Run another timer which have tick period - 10 min and on tick you unsubscribe from timer tick calling your function.
Note the start time. In each call, test if currentTime + 5 seconds > startTime + 10 minutes. If so, disable the timer.
I prefer this approach to just running for N ticks, as timers are not guaranteed to fire when you'd like them to. It's possible 120 ticks may run over 10 minutes of real world time.
You can set two timers one that run for 5 secs and the other one that run for 10min and disable the first one
You could use a second timer:
class Program
{
static void Main(string[] args)
{
int interval = 5 * 1000; //milliseconds
int duration = 10 * 60 * 1000; //milliseconds
intervalTimer = new System.Timers.Timer(interval);
durationTimer = new System.Timers.Timer(duration);
intervalTimer.Elapsed += new System.Timers.ElapsedEventHandler(intervalTimer_Elapsed);
durationTimer.Elapsed += new System.Timers.ElapsedEventHandler(durationTimer_Elapsed);
intervalTimer.Start();
durationTimer.Start();
}
static void durationTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
intervalTimer.Stop();
durationTimer.Stop();
}
static void intervalTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//call your method
}
private static System.Timers.Timer intervalTimer;
private static System.Timers.Timer durationTimer;
}

Categories

Resources