My issue is pretty simple.
I have an application that should be executed automatically once a day. I have no prior experience with this kind of scenario (some time ago I worked with IBM Control-M but guess that it is way more complete, complex and expensive =))
I thought about two possible solutions:
Creating a Task inside Windows Task Scheduler, which would execute the application;
Implement the application as a Window Service which would run 24/7, but only would perform the needed actions depending on the current time.
Which are the advantages/disadvantages of each approach?
Is there another way to do this?
Thanks in advance.
If it only executes once a day (or so) then just do it as a regular command line app that is executed by the windows task scheduler. Task scheduler already has all of the UI necessary to determine when to kick off the program, pass in parameters and anything else related to the scheduling of the task.
The only real reason to do this type of function as a windows service is if it needs higher execution resolution than once a minute. However, the main downside to a windows service is that you would have to manage the logic for how often/when to kick it off. Another one is that the app is always running, which leaves open the possibility for leaked memory if your code has issues.
On Unix/Linux you would use a cron job schedule a task to be executed. MS Windows' version is called the Task Scheduler and it is already a service that run 24/7 and performs the needed actions depending on the time.
Create a repeating task with the Task Scheduler to run your application. Creating, installing and configuring a service application is not exactly trivial. It's a much more involved process than creating a standard Forms or command line app and you don't need to do it anyway.
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-csharp/70633/Waitable-Timer-in-C
Another library that might be of interest is Quartz.NET
Related
I've been building a web service to synchronize data between SalesForce and Zendesk at my company. In the process of doing so, I've built several optimizations to drastically reduce execution time, such as caching some of the larger datasets that are retrieved from each service.
However, this comes at a price. When caching the data, it can upwards to 3-5 minutes to download everything through SalesForce and Zendesk's APIs.
To combat this, I was thinking of having a background worker that automatically cached all the required data every day a midnight. However, I'm not sure what the best method of doing this would be.
Would it suffice to build a class that merely has a worker thread that checks every several minutes to see if it is after midnight, and activate it on launch from Global.asax. Or is there some sort of scheduler already in existence?
EDIT
There seems to be some division between using something like:
FluentScheduler or Quartz.net to house everything within my applications.
Versus using something like windows task scheduler and writing a secondary application to call a function of my application to do so. It seems that using a third party library would be more simple, but is there any inherent benefit to using the Windows Task Scheduler.
I think you want to add your data caching logic to a project of type "console application". You'll be able to deploy this to your server and run it as a scheduled task using windows "Task Scheduler". If you've not worked with this project type or scheduled tasks before there are stack overflow questions which should help here, here, and here. You can add command line parameters if you need and you should have a look at adding a mutex so that only one instance of your code will ever run at once.
add an endpoint that will know how do it and use the windows task scheduler to call that new caching endpoint.
I have a web application and I need a specific process to run in background (all the time) and update the DB from time to time. What's the best way to do it? Create a controller with a method and run it in a thread in background? Any other option?
Your best bet is to create a separate application which you can run as a Windows Service or, if it's only a periodic update, a Scheduled Task.
The benefit of using a Scheduled Task is that you don't have to write the scheduler code - it's all handled for you by the operating system. Your application just consists of the code needed to update the database.
By divorcing it completely from your web application, it makes it more secure and easier to maintain (you can update either the web application or service independently of each other).
I am creating a web application in which I need to allow the user to schedule the excecution of a task.
I have gone through the various threads for scheduling the task but all of them are using windows service that I am not aware of. Moreover I cannot install visual studio in the server systems due to budget constraints.
Is there a way to create a method that runs a scheduler in a background thread in the asp .net application.Any code sample will be of great help.
That's not the way to go. If you need a scheduled task you should create a console application and run it using the Windows task scheduler.
You could create an application that sends an email to the user with a link to the page where the task is supposed to be done.
One thing to understand is that ASP.NET is intended to service requests from the network.
Everything in it is geared towards that. So, yes, you can run background tasks, but there are a number of caveats and gotcha's.
For instance, IIS will shut down your ASP.NET application if it does not receive any requests for some period. Also, your Application may be restarted without warning, if it detects changes to the file system. So, running code will be aborted.
That's not to say you can't work around these, but it's really not the best fit for scheduled task execution.
Your best bet would be to store the details of the task in a database, and then using either a single always-running Windows Service (really not that difficult to do, there are plenty of examples), or a console application (as suggested) scheduled manually to run regularly, to execute these tasks.
You may find that a library such as Quartz.NET may be of help scheduling/running these tasks.
I have a Windows Service that is meant to run a 2-minute job once a day. The remaining 23:58 of the day, it just sits around looking pretty.
My question relates firstly to the idle time: is it better to use a Timer.Tick, or a Thread.Sleep? Is there any difference between the resources either of these use?
Secondly, during that idle time, if someone shuts down the Windows Service, do I need to interrupt those idle threads for the program to shut down cleanly, or will the Shutdown handle it for me?
Thirdly, am I barking up the wrong tree by using a Windows Service? It would seem to make sense to put a record into the Windows Task Scheduler, but I couldn't find any way to do that using InstallShield, which is what we're using to deploy our product. Any better ideas?
If you start a background thread with ThreadPool.QueueUserWorkItem I think you could have a Thread.Sleep in there and when you shut the service down you would not have to do anything with it. I think Timer Tick would automatically do the thread creation for you when it ticks, so you would have to do even less if you used that (out of the two the timer tick would, I think match what you want to achieve better so would be the better choice).
This definately feels like something that would be better done by a scheduler like you say though. I don't know if you can do it directly within InstallShield but perhaps you could create a little console app that you run from the installer that based on a command line argument either talks to the windows task schedular API - http://msdn.microsoft.com/enus/library/windows/desktop/aa383614(v=vs.85).aspx to register itself or does the job you want to acheive (i.e -install - set it up on the schedular, no args do whatever it is you need to do once a day).
I think it is a C++ API so you could do a bit of p/invoke or, better, just have some managed C++ in a class libaray and reference it from a c# based console application.
FWIW, InstallShield doesn't have native capabilities to define scheduled tasks but it does support VBScript, C++ and InstallScript custom actions. All of these options support calling COM Automation Interfaces and Microsoft exposes the task scheduler through a series of Task Scheduler objects.
Task Scheduler Reference
CPU activity aside, a Windows service running all the time also consumes memory. In fact, every version of Windows has less services.
Why Windows 8 Uses So Much Less Memory Than Windows 7
I would use Timer.Tick. Thread.Sleep blocks the thread and you can not abort the thread nicely when you shut down your service.
I would recommend the Windows Service as you are just duplicating its functionality otherwise.
If InstallShield doesn't support adding to the task scheduler, then can you get InstallShield to run a batch script or a small .net app after install to add it to the task scheduler?
As long as your requirements for scheduling are very simple (as they currently are), I think the service approach is fine.
Personally, I don't really like the windows scheduler because I find it unstable and annoying to maintain (admittedly, I haven't tried the new version in Windows 2008).
I would probably go with a scheduling library like Quartz.Net if I were to build an application with more advanced scheduling requirements.
If you dont have scheduling app like autosys, windows service should be better option, also I dnt see any harm in thread.sleep, it is meant to pause app and utilize
0% cpu
Folks,
I want to develop a long running windows service (it should be working without problems for months), and I wonder what is the better option here:
Use a while(true) loop in the OnStop method
Use a timer to tick each n seconds and trigger my code
Any other options ?
Thanks
Essam
I wouldn't do #1.
I'd either do #2, or I'd spin off a separate thread during OnStart that does the actual work.
Anything but #1
The services manager (or the user, if he's the one activating the controls) expects OnStart() and OnStop() to return in a timely fashion.
The way it's usually done is to start your own thread that keeps things running and ofcourse, listens to an event that might tell it to stop.
Might be worth considering a scheduled task with a short interval. Saves writing a lot of plumbing code and dealing with the peculiarities of Windows Services timers.
Don't mess with the service controller code. If the service wants to stop, you will only make matters worse by using #1. And BTW the service can always crash, in which case your while(true) won't help you a thing.
If you really want to have a "running windows service (it should be working without problems for months)", you'd better make sure your own code is properly and thoroughly tested using unit and integration tests before your run it as a service.
I would NOT recommend #1.
What I’ve done in the past for the exact same scenario/situation is create a scheduled task that runs ever N seconds, kicks off a small script that simply does these 2 things: #1 checks for “IsAlreadyRunning” flag (which is read from the database) #2 If the flag is true, then the script immediately stops end exits. If the flag is false, the script kicks off a separate process (exe) in a new thread (which utilizes a service to perform a task that can be either very short or sometimes really long, depending on the amount of records to process). This process of course sets and resets the IsAlreadyRunning flag to ensure threads do not kick off actions that overlap. I have a service that's been running for years now with this approach and I never had any problems with it. My main process utilizes a web service and bunch of other things to perform some heavy backup operations.
The System.Threading.Timer class would seem appropiate for this sort of usage.
Is it doing a
1 clean up task, or
2 waking up and looking to see if needs to run a task
If it is something like #2, then using MSMQ would be more appropriate. With MSMQ task would get done almost immediately.