views:

355

answers:

12

How is this done best? I want an app that's running on a server to trigger an event every night at 03:00.

+22  A: 

Use windows task scheduler

klausbyskov
With this way the resources aren't wasted waiting around, if you try to keep the program running all the time.
monksy
I agree, in general, unless this is being added to an existing, all ready running service, and the "event" needs data from the service to function. In those situations, a Timer is potentially better...
Reed Copsey
i cold use windows task schefuler yeah, but how wold i do it with code is interesting to find out
Darkmage
You asked "how is this best done".
klausbyskov
Darkimage - do you absolutely need to do it from code? If it's an embedded system, you should have enough control to just setup the task, I'd think...
Reed Copsey
i dont have to but for practice i want to do it in code, and im makeing a timer on the form that counts down to when the event is triggerd.
Darkmage
A: 

Windows task scheduler (as suggested by klausbyskov) or a SQL Server job.

EDIT:

Or if you want a dyanically assigned time, you could create a windows service that polls every 10 minutes and performs some action at the desired time(s).

Mayo
+1  A: 

You could make a timer with an interval of 1 second and when the timer goes off, check if it's 3:00.

DaMacc
1 second intervals for something that happens once every 86400 seconds is overkill!
Reed Copsey
That's a busy-wait. It's a great way to waste energy and CPU power, but if Darkmage wants to use other programs on his machine, I don't recommend it.
Chip Uni
I know it is overkill but it will start exactly at 03:00... Also 1 small check every second isn't going to waste a lot of power.
DaMacc
1. if I had posted that I would have gotten downvoted :(. 2. every second is not neccessary. He did not say it had to start at 3:00:00 he said it had to start at 3:00. With those requirements, I would say once a minute should suffice.
Jrud
+1  A: 

There are two basic options here.

If you're trying to do this within an existing service, you can use a Timer to trigger yourself at 3:00 each night, and run your "task".

That being said, this is typically better handled via Windows Task Scheduler. Instead of keeping the application alive 24/7, you just schedule it to run once every day at 3:00.


Edit:

If you need to work with the Task Scheduler from code (mentioned in another comment), that is also possible. The Task Scheduler provides an API for setting up individual Tasks (ITask) via the Task scheduler (ITaskScheduler).

However, given that you're working on XP Embedded, you're probably better off just using the normal system configuration capabilities, and setting up a task to run once each day. In an embedded system, you should have enough control during your deployment to do this.

Reed Copsey
+1  A: 

You'll need to build it in a service in order to ensure that it runs even if there's nobody logged into the machine, and then there are lots of different methods to ensure that the trigger occurs.

Consider making a System.Timers.Timer where the Interval is set to the difference between DateTime.Now and the next 3:00.

md5sum
A: 

It depends on what you have available to you.

Your best bet is to use a cron job, if you are on linux/unix/OS X, a task scheduler on windows, or launchd on newer versions of OS X.

If you want to do this from within an app, you would need a loop that checks the time on a regular basis and fires off the event if it is 03:00, but this isn't ideal.

Jeff B
A: 

Creating a windows server in C# is fairly trivial and could do this. Just make sure you've got the security and logging figured out because it can be pretty hard to tell what's going on while it is (or isn't) running.

Andrew Lewis
A: 

Use System.Threading.Timer.

I'm spawning a thread in an ASP.NET application to do scheduled tasks.

George
A: 

Here is a simplified version of a service that we wrote that runs a timer every 60 seconds to watch a table... you could alter the timer elapse event to check the time and run it then:

Dim Timer As System.Timers.Timer

Protected Overrides Sub OnStart(ByVal args() As String)
    Timer = New System.Timers.Timer(60000)
    AddHandler Timer.Elapsed, AddressOf timer_Elapsed
    Timer.Start()
End Sub

Protected Overrides Sub OnStop()
    Timer2.Stop()
End Sub

Private Sub timer_Elapsed(ByVal pSender As Object, ByVal pargs As System.Timers.ElapsedEventArgs)
    'Ensure the tick happens in the middle of the minute
    If DateTime.Now.Second < 25 Then
        Timer.Interval = 65000
    ElseIf DateTime.Now.Second > 35 Then
        Timer.Interval = 55000
    ElseIf DateTime.Now.Second >= 25 And DateTime.Now.Second <= 35 Then
        Timer.Interval = 60000
    End If

    'Logic goes here
 End Sub

Obviously, if you can, use the task scheduler like everyone else here has mentioned. It is the preferred way of doing this. I just happened to have this code laying around so I thought I'd post it in case it could be helpful to you. Also, this code worked for us because we never knew when an external source was going to edit a table. Setting the interval to a correct number of milliseconds would be a much more efficient way of doing this, as pointed out by md5sum.

Jrud
+1  A: 

If you want to do this in running app code (instead of using a task scheduler), you should choose a duration to let your app sleep that's fairly long (e.g., 1 hour, or 3,600 sec). Your app loops, and as each sleep call expires, the app periodically checks how much time is left until the deadline time (03:00). Once the remaining sleep time gets below the coarse interval time, it should be reduced to a shorter interval (halved each time, or reduced to 10 sec). Continue the loop, sleeping and reducing the interval time, until the target deadline time is reached.

This prevents the loop from waking up too often (86,400 1-sec intervals is overkill), but it also prevents the app loop from overshooting the target deadline time by sleeping too long.

Loadmaster
good point, ill implement a plan based on this and what DaMacc says.
Darkmage
A: 

This answer might be a bit left field but we often use CruiseControl.net for some of our scheduled tasks. Its not perfect for them all but if its a big job that you want to run every night and other code/outcomes depend on it then its a good choice. You can schedule it to run whenever, get emails if it worked/failed. Run other scripts/code if it did not work, clean up files you need before you start and after.

Not the perfect solution to all situation but it is damn powerful for those that call for it. We use it for some of our big data processing jobs and it sends us all an email if it worked/failed and will even try again 30 minutes later if it failed the first time. Gives you a nice fussy feeling :)

Pete Duncanson
A: 

Is the program able to run via command line? If so... create a foo.bat file.. and call your program command line. (very simple)

then use the task scheduler to run the .bat file at 3am daily.

Kirby