Windows service to do job every 6 hours - c#

I've got a windows service with only two methods - one private method DoWork(), and an exposed method which calls DoWork method. I want to achieve the following:
Windows service runs DoWork() method every 6 hours
An external program can also invoke the exposed method which calls DoWork() method. If the service is already running that method called from the service, DoWork() will again be invoked after the current method ends.
What's the best approach to this problem? Thanks!

An alternative approach would be to make use of a console application which can be scheduled by Windows task scheduler to run every 6 hours. In that case you don't waste resources to keep the Windows service running the entire time but only consume resources when needed.
For your second question: when you take the console app approach you can have it called by making use of Process.Start for example.

If the purpose of your application is only to run a specific task every six hours, you might be better off creating a command line application and creating a scheduled task that Windows runs automatically. Obviously, you could then manually start this application.
If you're still convinced you need a service (and honestly, from what I've seen so far, it sounds like you don't), you should look into using a Timer, but choose your timer carefully and read this article to get a better understanding of the timers built into .NET (Hint: Pay close attention to System.Timers.Timer).
To prevent reentry if another method tries to call DoWork() while the process is in the middle of performing its operation, look into using either a Mutex or a Semaphore.

there are benefits and drawbacks either way. my inclination with those options is to choose the windows service because it makes your deployment easier. scheduling things with the windows task scheduler is scriptable and can be automated for deployment to a new machine/environment, but it's still a little more nonstandard than just deploying and installing a windows service. you also need to make sure with task scheduler it is running under an account that can make the webservice call and that you aren't going to have problems with passwords expiring and your scheduled tasks suddenly not running. with a windows service, though, you need to have some sort of checking in place to make sure it is always running and that if it restarts that you don't lose hte state that lets it know when it should run next.
another option you could consider is using nservicebus sagas. sagas are really intended for more than just scheduling tasks (they persist state for workflow type processes that last for more than the duration of a single request/message), but they have a nice way of handling periodic or time-based processes (which is a big part of long running workflows). in that a saga can request that it get back a message from a timeout manager at a time it requests. using nservicebus is a bigger architectural question and probably well beyond the scope of what you are asking here, but sagas have become how i think about periodic processes and it comes with the added benefit of being able to manage some persistent state for your process (which may or may not be a concern) and gives you a reason to think about some architectural questions that perhaps you haven't considered before.

you can create a console application for your purpose. You can schedule the application to run every 6 hours. The console will have a default method called on application start. you can call your routine from this method. Hope this helps!!

Related

Launching a long-running background task - from ASP.NET or a scheduled job

I have a fairly long-running process (several minutes) that I need to run roughly once a month - but not on a fixed schedule, but after a user clicks Go in a ASP.NET Webforms GUI page.
Since ASP.NET really isn't designed to handle long-running background tasks, my idea was to put this into a separate console app. But how to launch that as needed?
What happens if I use Process.Start(....) from my ASP.NET page's code-behind? I would like to avoid blocking the whole Web UI for 20 minutes or so... and also: even if it doesn't block my UI, what happens to my long-running task if the ASP.NET app pool recycles while it's still running?
Another idea was to have a frequently running job (runs every 2 minutes) check for some kind of a flag (e.g. existence of some database entries), and if needed, that job would then launch the long-running task.
But the same question: if I launch my 20-minute task from a job using Process.Start() - does that block the caller?
It seems like a bit of overkill to schedule that long running tasks five times a day since it typically is run only once a month - but at the same time, the user expects to have his results within a reasonable amount of time (less than 1 hour, if ever possible) after scheduling the process - so I cannot really just schedule it to run once at night either ...
Hangfire is what you are looking for. Best part is it comes with a built in dashboard.
You might have to write some logic on the top of it.
You can find it here.
http://hangfire.io/
First off - for several reasons - ASP.NET is imho not the solution for long-running tasks/jobs/... whatsoever.
I have had this requirement a lot of times, and always solved/separated it like:
Worker
A service with
Quartz.net (for scheduling and processing, even if you don't have a specific timestamp for execution - but the overall handling in this framework is simply superb)
a persistent job-store (to handle start/stop and completed/aborted/paused jobs)
eg ServiceStack as the interop between the two processes
Website
Simply calls some webservice-methods of the worker to enqueue/query/pause/stop/... a job. For querying jobs a call to a unified job-store might be an option (eg. db)
It might be a bit of an overkill for you though ... but this is my Swiss army knife for such scenarios.
Use the standard built-in Windows Task Scheduler like you have done, but invoke it from your web application.
Configure your task in Task Scheduler. It does not need to have a scheduled trigger. From your web application, just use Process.Start to kick it off:
SchTasks.exe /Run /TN Folder\Taskname
I have not used SchTasks.exe directly, but have used the Microsoft.Win32.TaskScheduler wrapper classes.

BackgroundWorker vs. Android Service in Xamarin

I'm investigating about mobile apps using Mono on Visual Studio.Net.
Currently we have an application we want to translate to Android from Windows CE. The original program used small BackgroundWorkers to keep the UI responsive and to keep it updated with the ProgressChanged event. However I have been reading that in Android there are Services that can replace that functionality.
Reading pros and cons about services I know that they are usually used because they have a better priority than threads and, mainly, if the functionality will be used in more than one app.
More info I have found comparing threads and Services say that Services are better used for multiple tasks (like downloading multiple files) and threads for individual tasks (like uploading a single file). I consider this info because BackgroundWorker uses threads.
Is there something I am missing? Basically a service should be for longer tasks because the O.S. gives it better priority (there are less risk it will be killed) and Threads/BackgroundWorkers are better for short tasks. Are there any more pros/cons to use one or the other?
Thank you in advance!
[Edit]
If you need a very specific question... how about telling me when and why would you use a Service instead of a BackgroundWorker? That would be useful.
Some of the functionality I have to recreate on Android:
- GPS positioning and compass information - this has to be working most of the time to get the location of the device when certain events are working and trace in a map its movements.
- A very long process that might even be active for an hour.
The last one is the one I am concerned about. It must be very reliable and responsible, keeping the user informed of what it is doing but also being able to keep working even if the user moves to other activity or functionality (doing a call, hitting the home button, etc.)
Other than that I believe the other functionality that used BackgroundWorker on WinCE will not have problems with Android.
[Edit 2: 20140225]
However I would like to know if the AsyncTask can help me in the next scenario:
- The app reads and writes information from/to another device. The commands are short in nature and the answer is fast so for individual commands there is no problem. However there is a process that can take even an hour or so and during that time it will be asking the status from the device. How would you do it?
I think you're misunderstanding what a Service in Android is. See the documentation on Services:
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application.
Also note:
A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise).
Using a worker thread and using a Service are not mutually exclusive.
If you are looking to move work off the main thread, then clearly you need to use another thread. Through a BackgroundWorker or perhaps the TPL will do just fine in many cases but if you want to interact with UI (e.g. on completion of the task or to update progress in the UI), the Android way is to use an AsyncTask (mono docs).
If this work needs to continue outside of the user interaction with your application, then you may want to host this work (including the BackgroundWorker/Thread/AsyncTask/etc.) in a Service. If the work you want to do is only ever relevant while the user is interacting with your application directly, then a Service is not necessary.
Basically, a service is used when something needs run at the same time as the main app - for example keeping a position updated on a map. A thread is used when consuming a webservice or a long running database call.
The rule-of-thumb, as far as I can see, is rather use threads and close them, unless there is something that needs to happen in the background (like navigation updates). This will keep the footprint of the app smaller, which is a large consideration.
I hope this helps at least a little.
Now that you know you don't need a Service, I want to point out how is the Xamarin guideline doing/recommending this: create a separate thread using ThreadPool and when you want to make changes to GUI from that thread, you call the main thread to do them using the RunOnUiThread method.
I'm not sure that by using AsyncTask you can write your code inline in c#, but with Xamarin recommendation you certainly can, like so:
//do stuff in background thread
ThreadPool.QueueUserWorkItem ((object state) => {
//do some slow operation
//call main thread to update gui
RunOnUiThread(()=>{
//code to update gui here
});
//do some more slow stuff if you want then update gui again
});
http://developer.xamarin.com/guides/android/advanced_topics/writing_responsive_applications/

Is it wise to use timer(s) with a windows service?

I have a console service I'm currently testing. I was planning on using a timer for it to last all day, with an interval check every 30 seconds, however, it looks like alot of people don't like using timer's with a service in that fashion. Is It wise to use a timer? or is their a better method to approach it?
It's fine to have timers inside a service.
The question you should be asking yourself is whether you need your own service, or can just leverage a service that's already running timers (Task Scheduler). Or perhaps you should instead be responding to a user action.
I suspect they are trying to get you to do it using a thread based method this way, which is arguably superior as the wait method is designed to awake correctly in response the the service interface.
If you need to launch very frequently the service approach is better than a scheduled task.

C# code that run constantly - service or separate thread?

I have a .NET 4 web application that has 3 separate projects associated – DAL, BAL, and UI. I am using Entity Framework for database interaction.
I have code that cycles through a bunch of database data, calls methods depending on what it finds, and then updates a database. I want this code to run all the time. At the same time I want users to be able to log in and run reports etc all while the code in the background is constantly running.
What is a good approach to this? Do I create a service for the code that constantly runs, a separate thread, an entirely separate project for the code that runs constantly, or a different approach..?
Also, depending on the answers given, how would I kick start the code that runs constantly? i.e. just through form load method or is there a better approach? I currently kick start the code by clicking a start button; this is fine for testing, but not going to work when in production.
You would be best suited for using Windows Services for always-running tasks.
Running code on a separate thread under IIS is not a reliable mechanism since IIS can terminate threads at will to conserve server resources.
Given your question and clarifications on other answers that:
Your solution runs in a hosted environment where you cannot install a service;
Calling it from a third server (i.e. Azure or such) is not an option for you;
You might be best off starting a thread in your Application_Start event to manage the database work. You'd probably want to ensure that this thread had some periodic idle time, so as not to take up too much of the hosted environment and ensure it's shutdown when your application ends or is restarted.
A service would really be optimal, but if you're in a hosted environment and can't/won't use another server, then that's not possible.
Use a Windows Service. Should also look into using Stored Procs for the database interactions you mentioned. In terms of kicking the Windows Service off, you can set it to automatic startup (when the OS starts) which will mean it will run until terminated.
I would only recommend a Windows Service if it will literally always be running. However, "always" usually means every x seconds / minutes / hours /days.
If x is greater than a few minutes, I would make it a Console Application and run it through the Windows Task Scheduler. This way you don't have to worry about memory leaks and a slew of other issues.
However, if it is only working with the database, I would recommend a stored procedure and a Sql Job.

Simulating a cron job with a Task in Application Start

I'm trying to find a very easy easy way to start a simple cron job for my Web Application. What I was thinking about is starting a Task in the Application_Start event. This task will have a while loop and do some action every hour or so like a normal cron job would do.
Is this a good idea or will this give some trouble?
Some of the problems I could think of are the following:
The Task suddenly stops working or hangs. Maybe make some fail over
mechanism that would check if the task is still running and if not
restart it.
Memory leaking if the Task totally goes wrong and I have to restart
the whole application.
No control in changing the Task on the fly but this shouldn't be a
problem for the thing I want to do but for others it might be.
Does someone have any suggestions or experiences with trying this?
Although Darin says that doing cron jobs in a web application is a bad idea (and I agree with him in some way), it may be not so bad, when used wisely and for short running jobs.
Using same Quartz.NET in web application may be quite nice, I'm using in one of my projects like this
http://bugsquash.blogspot.com/2010/06/embeddable-quartznet-web-consoles.html for small jobs and it is running nice - it's easy to monitor (easier than monitoring remote windows process), may be used on shared hosting.
Doing cron jobs in a web application is a bad idea. IIS could recycle the application at any time and your job will stop. I would recommend you performing this in a separate windows service. You could take a look at Quartz.NET. Another possibility is a console application which does the job and which is scheduled within the Windows Scheduler.

Categories

Resources