Question

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

Was it helpful?

Solution

Use windows task scheduler

OTHER TIPS

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.

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

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.

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.

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.

This answer might be a bit left field, but we often use CruiseControl.NET for some of our scheduled tasks. It's not perfect for them all, but if it's a big job that you want to run every night and other code/outcomes depend on it then it's 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. It gives you a nice fuzzy feeling :)

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).

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.

Use System.Threading.Timer.

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

It depends on what you have available to you.

Your best bet is to use a cron job, if you are on Linux/Unix/Mac OS X, a task scheduler on Windows, or launchd on newer versions of Mac OS X.

If you want to do this from within an application, 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.

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 Task Scheduler to run the .bat file at 3 a.m. daily.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top