I have a site that I'm working on. Say I need something to run every... say... 30 minutes, how would I get just a simple thing to run like that?
EDIT
I'll be hosting this online with another company. This is why I am not making it as a separate scheduled program.
If you need a process to be run at pre-defined intervals you might be better off using the windows task scheduler, or to create a windows service with a timer. ASP.NET applications aren't ideal for doing this sort of thing, since they are vulnerable to restarts and so you can't guarantee that the process will run at the given interval.
Windows scheduled tasks and services are ideal for this but if you want to run database queries at specified times then I would suggest using SQL Server Agent if you have access to this.
I don't know of any way to reliably do this using ASP.NET. My understanding is: after a certain period of inactivity, IIS will unload your website/webspp from memory. If that happens, your periodic job very likely won't execute, regardless of what technique you used to configure it.
You could, of course, set up some kind of automated system on your own, which occasionally pings your site to keep it from being unloaded. But if you're doing that anyway, well you could just set it up to do the desired operation at the desired interval. :)
Related
client wants an asp.net page that has a button to fire off a database update from an external source with hundreds of records. This process takes a long time. He also wants status update as the process runs, like "processing 10 out of 1000 records". In reading various articles, I'm thinking of putting the database update code in a windows service. I've never worked with windows services before and I can't find many tutorials on how to fire off a windows service and poll it from an asp.net page. My questions are is this the best way to handle this process? And, does anyone have any examples on how they've accomplished this?
There are a few ways to approach this.
You're right in that executing a long-running task within the Web's worker process doesn't usually end well: it ties up resources, the app pool can get recycled, etc. In most of my projects of any complexity, I usually end up with 4 pieces: the database, a DLL with my model, a "Worker" that is a Windows service, and an ASP.NET Web site.
The "Worker" is a Windows service that is always running and uses Quartz.net to execute scheduled tasks using the same model that the Web site uses. These can be all sorts of periodic tasks that seem to crop up when maintaining a Web site of any complexity: VacuumExpiredPickTicketsJob, BackupAndFtpDatabaseJob, SendBackorderReminderEmailsJob, etc.
Writing a Windows service is not difficult in C# (there is a built-in template in Visual Studio, but you pretty much inherit from ServiceBase and you're off to the races), and libraries like TopShelf make it even easier to deploy them.
What is left is triggering the update from the Web site and communicating the results back to the user. This can be as simple or as complicated as you want it to be. If this is something that has to scale up to lots of users, you might use something like MSMQ to queue up update commands to the Windows service, and the Windows service would respond to that queue. I get the impression that that is probably overkill here.
For a handful of users, you could override your service's OnCustomCommand(int command) method to be the trigger. Your Web site would then use ExecuteCommand() of the ServiceController class to get the process started. Your Web site and service would agree on the parameter value that means "do that update thing," let's say 142 (since it has to be a number between 128 and 255 for reasons of history).
As for communicating progress back to the client, it's probably easiest to just have the Web page use a timer and an AJAX call to poll for updated progress data. You can get fancy with new stuff like WebSockets (bleeding edge stuff as I write this) and long polling, but regular polling will simply work for something that doesn't need to scale.
Hope this helps!
In addition to Nicholas' thorough answer, another option is to deploy your back end processes as command line scripts, and schedule them to run through Window's built in task scheduler, which has improved quite a bit in Windows Server 2008+. Or you can use any other host of task scheduler applications.
I find the command line approach to be easier for MIS staff to understand and configure, and to migrate to new servers, versus standard Windows services.
My web site stores invoices.
I would like to process them every night at midnight.
I would also like to send out notices nightly at midnight.
But the web is stateless.
I do not have my own server.
Is there a way?
No, you need a Windows Service on a dedicated box, however the box can be virtual and in the cloud.
You do not own your own server, but your website must be hosted somewhere. You may want to see if you can install windows services on to that server. If you can, I would strongly recommend using a service to run any automated tasks. It is generally frowned upon to use IIS to run automated tasks simply because the process shuts down after periods of inactivity... and if IIS isn't running, neither will your automated task.
A similar question was asked a while back and I think the answers are still very relevant to your problem: Best way to run scheduled tasks
And even further, after google searching I found even more info which you might find helpful:
https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/
http://www.codeproject.com/KB/aspnet/ASPNETService.aspx
If you absolutely cannot install a service, you could try something like creating a new thread on Application_Start() that checks the time and decides whether or not to run. Then, to keep IIS running during periods of inactivity, you could possibly try spawning a process or something every few minutes to send a request to your server and thus keep it from shutting down.
We have a long running data transfer process that is just an asp.net page that is called and run. It can take up to a couple hours to complete. It seems to work all right but I was just wondering what are some of the more popular ways to handle a long process like this. Do you create an application and run it through windows scheduler, or a web service or custom handler?
In a project for long running tasks in web-application, i made a windows service.
whenever the user has to do the time-consuming task, the IIS would give the task to the service which will return a token(a temporary name for the task) and in the background the service would do the task. At anytime, the user would see the status of his/her task which would be either pending in queue, processing, or completed. The service would do a fixed number of jobs in parallel, and would keep a queue for the next-incoming tasks.
A windows service is the typical solution. You do not want to use a web service or a custom handler as both of those will lie prey to the app pool recycling, which will kill your process.
Windows Workflow Foundation
What I find the most appealing about WF, is that workflows can be designed without much complexity to be persisted in SQL Server, so that if the server reboots in the middle of a process, the workflow can resume.
I use two types of processes depending on the needs of my BAs. For transfer processes that are run on demand and can be scheduled regularly, I typically write a WinForms (this is a personal preference) application that accepts command line parameters so I can schedule the job with params or run it on demand through an interactive window. I've written enough of them over the last few years that I have my own basic generic shell that I use to create new applications of this nature. For processes that must detect events (files appearing in folders, receiving CyberMation calls, or detecting SNMP traps), I prefer to use Windows Services so that they are always available. It's a little trickier simply because you have to be much more cautious of memory usage, leaks, recycling, security, etc. For me, the windows application tends to run faster on long duration jobs than they do when through an IIS process. I don't know if this is because it's attached to an IIS thread or if its memory/security is more limited. I've never investigated it.
I do know that .Net applications provide a lot of flexibility and management over resources, and with some standards and practice, they can be banged out fairly quickly and produce very positive results.
We require that in a ASP.Net application, a .Net process should be invoked every day at a specified time automatically. This process needs to interact with the database (SQL Server 2005) and generate billing on a daily basis. We are using a shared hosting hence we are not able to create a windows service or create SQL Server jobs. How can this be achieved without user intervention?
You could try the technique described here, used at StackOverflow itself (or at least it was used here at one point). In a nutshell:
At startup, add an item to the HttpRuntime.Cache with a fixed
expiration.
When cache item expires, do your work, such as WebRequest or what have
you.
Re-add the item to the cache with a fixed expiration.
To get it to run at a specific time instead of an interval, you could lower the interval and simply modify your working method to check the time itself.
As the comments in the original article linked above note, this isn't a perfect solution, and no one should prefer it over a proper scheduling technique if one is available. See When Does Asp.Net Remove Expired Cache Items? for some additional qualifications.
Yes, use Windows Scheduler. Depending on how it's configured you might need to be logged in for the scheduler to run.
You could always schedule a task to run a webservice..
http://weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx
The scheduler would run a VBS file with the following..
Set oServerXML = CreateObject("Msxml2.ServerXMLHTTP")
oServerXML.Open "GET","http://my.hostedservice.com/myService.asmx/myService?aParam=Value
oServerXML.setRequestHeader "Content-Type","application/x-www-form-urlencoded"
oServerXML.Send
Set oServerXML = nothing
Can't be done, unfortunately.
IIS only responds to requests, and SQL Server only wakes up for jobs.
The closest you'll be able to do is to put your routine in an ASPX page, not linked from the site and not with an obvious name, and trigger it by a request from some other machine out on the Internet.
The other machine could be a Windows, Linux, Mac, whatever you have available, and all of those platforms have ways of scheduling events (service, cron, etc.) that can make the request to trigger the update on the server.
There are ways to run "services" in .Net by using cache expiration to trigger the task.
More at CodeProject
You can use a Scheduled Task, but this might not work in a shared hosting environment either.
You could setup a webservice or page on your website to kickoff the process, then have a scheduled task on a desktop machine hit that page/service once daily to start the process. Hacky, but it might work.
Being .NET ignorant, I would imagine there's some kind of .NET based scheduler framework available for this (much like Quartz for Java).
Or you could simply fire off a long running thread that spends the bulk of its time sleeping, wake up every minute, check the time, check it's list of "things to do", fire off the ones that need to be done. Level of sophistication being as far as you want to take it, but the primary goal of keeping the primary scheduling thread "alive", "at all costs".
What i can think about now are:
Create a dll which contain the
schedule logic you want, and make
sure that this dll schedule function
will not stop and will loop for ever,
then you will need a page on that
server this page will fire this dll
functions. "you will need to call
this page at least once to start the
scheduler".
Create an application "holds schedule logic" on another machine, may be your Home PC, and make your pc application call the functions on the server through webservices or pages
We have an ASP.Net application that provides administrators to work with and perform operations on large sets of records. For example, we have a "Polish Data" task that an administrator can perform to clean up data for a record (e.g. reformat phone numbers, social security numbers, etc.) When performed on a small number of records, the task completes relatively quickly. However, when a user performs the task on a larger set of records, the task may take several minutes or longer to complete. So, we want to implement these kinds of tasks using some kind of asynchronous pattern. For example, we want to be able to launch the task, and then use AJAX polling to provide a progress bar and status information.
I have been looking into using the BackgroundWorker class, but I have read some things online that make me pause. I would love to get some additional advice on this.
For example, I understand that the BackgroundWorker will actually use the thread pool from the current application. In my case, the application is an ASP.Net web site. I have read that this can be a problem because when the application recycles, the background workers will be terminated. Some of the jobs I mentioned above may take 3 minutes, but others may take a few hours.
Also, we may have several hundred administrators all performing similar operations during the day. Will the ASP.Net application thread pool be able to handle all of these background jobs efficiently while still performing it's normal request processing?
So, I am trying to determine if using the BackgroundWorker class and approach is right for our needs. Should I be looking at an alternative approach?
Thanks and sorry for such a long post!
Kevin
In your case it actually sounds like the solution you will be looking for is multifaceted (and not a simple in and done project).
Since you said that some processes can last for hours that is absolutely not something for ASP.NET to own. This should be ran inside a windows service and managed with native windows threading.
You will need to implement some type of work queue in your service and a way to communicate with the queue. One way is to expose a WCF service for all actions your service will govern. Another would be to have service poll a database table and pick up work from the table.
To be able express the status of the process you will want the ASP.NET application to be able to have some reference to the processID for example the WCF service returns a guid identifier. Then you have a method that when you give it the processID it will return the status of the process. You can then implement the polling of that service call using AJAX and display any type of modal you wish.
Another thing to remember is that you need to design your processes to have knowledge of where it is and where it will be when it is finished so it can track the state it's in. For example, BatchJobA is run and will have 1000 records to process. The service needs to know what record it's on or what the current % of competition is for it to be able to return information to the UI. For sql queries that take a very long time to execute this can be very problematic to accurately gauge where it is unless you do alot of pre and post processing of temp tables that you can in the middle of it read the status of the temp tables to understand where it is.
Based on what you are saying I think that BackgroundWorker is not a good choice.
Furthermore keeping this functionality as a part of your main app can be problematic, specifically because you do not want the submitted processing to be interrupted if the main app recycles. You can play with asynch processing but it still will be a part of the main app AppDomain - all of it will die if the app recycles.
I would suggest buidling a separate app implementing this functionality. In a similar situation I separated background processing to a Windows service and hosted a web service in it as a means of communication
You might consider a slightly different approach.
For example, have a command and control table in which you send commands like "REFORMAT PHONE NUMBERS" or whatever.
Then have a windows service monitoring that table. Whenever a record shows up, run the command.
This eliminates any sort of worry about a background thread. Further you have a bit more flexibility with regards to what's in the queue, order of operations including priority, etc. Finally, you would have a definitive list of what is running or needs to run.
As an option, instead of a windows service you might just use a SQL job to execute every so often to watch your control table and perform the requested action.