windows service versus asp.net Application_BeginRequest event with threads/timers - asp.net

What are the advantages/disadvantages to running time based jobs using:
windows services
Application_BeginRequest to start seperate threads / timers.
One disadvantage of running the jobs in the context of a asp.net web appplication is during .net recycling things will have to be setup again, any others?

To my mind, there's no real benefit to doing time-based things in a web app. Go straight to a windows service. You know the process should be up and running all the time.
The ASP.NET site may simply unload, and will only operate again once someone starts browsing. The lifecycle is all wrong -- it's much 'choppier' than a service.
Lastly, services aren't very hard to create.

If you have administrative access to the server, I would either run a Windows Service or a scheduled SQL job depending on what you are trying to achieve.
It is nice to be able to stop/start and log these jobs independent of your web application. Also, if you have problems or errors in the job, it could adversely affect your website.
Finally, you are forcing the web application to go through code at every request to see if the timer has elapsed, which is an unnecessary overhead.
As I said to start with, the implementation depends on what the job is. If it is simply to update a number of database records, I'd use a scheduled job in SQL Server. If you need file I/O or access to external services, then a Windows Service might be more appropriate.
It is worth noting that you need to build in your own scheduling and thread safety into Windows Services. An alternative is to build a console application and use an application like FireDaemon for the scheduling.

Related

Setting up DLLs so we can update production ASP.NET app w/o full publish or app restart

We have DLLs that contain hundreds of custom client processes that are kicked off from an ASP.NET application. Our clients run these processes while performing data entry, and typically there's only 1 process per client. On any given day, we might update 2 or 3 of these processes.
Currently these are all housed in a series of DLLs, which means that we are publishing our application a couple times per day. As a result, any logged-in clients get booted out of the system since the publish causes an app restart.
Is there a way that we can update these DLLs without requiring a full publish each time?
If your client processes have a common API then you could host, the DLLs separately in a WCF (or similar) service, and call the client processes remotely. So basically, consider moving to a service oriented architecture.
Check out the Managed Extensibility Framework (MEF) from Microsoft. It provides not only dependency management but also plug-in like library loading. Most likely it's exactly what you're looking for.
You can switch to SQL server or state server sessions in order to perserve session and logged users after app restart. Or store these dlls in APP_DATA and load it dinamically. Then of course you have to think of some refreshing system and refresh loaded dlls with newly uploaded ones.
There is no sensible way to avoid an application restart. Please note the emphasis on the word sensible.

How to warm up an ASP.NET MVC application on IIS 7.5?

We would like to warm up an ASP.NET MVC application hosted on IIS 7.5 server. The warm up module that used to be available at http://forums.iis.net/t/1176740.aspx has been removed since sometime.
The application should be warmed up everytime IIS or ASP.NET worker-process restarts for any reason. During the warm up period, IIS should return some HTTP status code signifying its warm up state or its inability to serve any clients.
Would creating a executable that navigates through necessary pages in the site via HttpRequests be a good idea? The executable can be triggered from IProcessHostPreloadClient implementation. Is it possible to configure IIS so that it would only accept requests from localhost and once the executable is done, it can switch over to all clients - but that switch should not trigger an IIS restart (obviously).
Is it possible to use an Visual Studio 2010 - Web Performance Test to warm-up an application instead of creating an manual executable? Any other alternatives?
PS: The application uses Forms Authentication and uses sessions - so maintaining state cookie and other cookies is important.
UPDATE 1 - We are using .NET Framework 4.0 and Entity Framework (database first) in our application. The first time hits to EF queries are slow. The reason behind the warm up is to get these first time hits out of the way. We are already using compiled queries at most places and we have implemented pre-compiled views for EF. The size of the model and application is very large and complex. Warm up needs to walk through many pages to ensure that compiled and non-compiled EF queries get executed at-least once before any end user gets access to the application.
Microsoft has released a module that does exactly what you ask for. The Application Initialization Module for IIS 7.5 improves the responsiveness of Web sites by loading the Web applications before the first request arrives.
You can specify a series of Urls that IIS will preload before accepting requests from real users. I don't think you can get a true user login expereince, but maybe you can set up simulated pages that does not require login that fulfills the same warmup you ask for?
The feature I think is most compelling is that this module also enables overlapped process recycling. The following tutorial from IIS 8.0 include a step-by-step approach on how to enable overlapped process recycling.
When IIS detects that an active worker process is being recycled, IIS does not switch active traffic over to the new recycled worker process until the new worker process finishes running all application initialization Urls in the new process. This ensures that customers browsing your website don't see application initialization pages once an application is live and running.
This IIS Application Initialization module is built into IIS 8.0, but is available for download for IIS 7.5.
You may take a look at the following post for the Auto-Start feature built into IIS 7.5 and ASP.NET 4.0.
Any application that generates a server request for the hosted resources can be used to warm up an IIS process. Exactly how many requests you need depends on what parts need warming up. Typically, warm-up is used for:
Starting up a worker process. For this, you only need to ask for one resource to warm up a process for the entire application.
Perform any static initialization, database startup, or pre-caching. Anything you do in your Global.asax file will happen when you do your first request, so if you can make all of your initialization happen then, you'll still only need to make one page request.
Force pre-compilation of ASP.NET pages. For this to happen you would need to hit every page. Fortunately, this is typically not much of a time cost, so you likely don't need to worry about it. If you do have individual pages that load slowly, you can warm them up separately.
The "warm-up" process here isn't anything magical. You just need force IIS to serve the URL in question. Everything you mentioned would take care of that: using a stress-test tool to query the URL, writing a custom utility to post HTTP requests, even just scripting out a tool like 'wget' or a PowerShell script to download the URLs would do it.
As far as restricting access to localhost, as far as I know, within IIS, the only way to change that requires you to restart IIS. You could always build a pre-request hook into your application and maintain the state there, and have your warm-up process query some specific URL that toggles that state to "open". But I'm not sure what you would accomplish. If, somehow, a user did try to query your site before your warm-up finished, all that would happen is your site would take a long time to respond, then they would eventually get the page they asked for. If you locked them out of the site during warm-up, they would instead get a browser network error that claimed the site was offline, which (to me) sounds much worse.

aspnet_wp.exe restart automatically

Our web-application is on .net 1.1 and we have some legacy code that hangs-up IIS after every couple of days.
I was thinking about modifying machine.config settings to restart aspnet process after every couple of days, but the problem is it's going to kill existing sessions in process. Can I avoid it somehow.
Is there a better way to deal with this situation? right now client restarts IIS manually after every couple of days.
Thanks,
A
Edit:
If you have
- un-serializable objects in your session,
- cant work with sql-server
Then the good work around is to use "idleTimeout". It shuts down asp_net process if there is no activity on the server until the time specified. On the next request, it spawns asp_net process.
I suggest two things:
Configure the application to use SQL Server to store session data - this allows the session data to survive a restart of the web application
Configure the application pool to recycle worker processes periodically:
Of course, even better would be to update the web application to a recent framework version and fix at the same time the problem to prevent this from happening in the first place.
Do you actually store any type of data in Session? if you do, is it Serializable? If it is, just change the Web.config to use StateServer.
You just need to start ASP .NET State Service automatically by going to control panel--> administrative tools --> Services and setting up ASP .NET State Server to start automatically.
This will allow you to restart the aspnet_wp.exe process w/o losing session information; again, the only requirement is that the information you put in session is Serializable (which is likely the case or at least should be easy to do if your the code is not doing anything crazy)

start batch job from IIS

What is the right approach when users (authenticated domain admins) should be able to start batch jobs (usually exe files) from an IIS (7.x) aspx (c#) page? This is an intranet site. The batch jobs have to run on the web server as Domain Admins. The website pool is executed by network service or some similar restricted account in AD.
Approaches I can think of (and their disadvantages):
1. Start exe file with System.Diagnostics.Process.Start with another account. This feature is disabled in IIS 7.x, how do I allow it?
2. Create a sheduled task and call scheduled task-api. This unmanaged dll is giving VS compiler warnings because it's unsafe to call from managed code.
3. I suppose there's a better approach, because the previous suggestions doesn't appear safe or robust.
I would suggest that you have either a Scheduled Task or Windows Service that polls a common storage repository to see if a batch job should be run - as batch jobs are typically used for long running process.
Your could persist the deatils of which batch file and arguments you want to run from your ASP.NET website into a database (MySQL, Oracle, SQL Server, etc) and then have your Windows Service / Scheduled Task poll against this database at regular intervals.
I agree with Kane. However, if you must do...
http://www.dotnetscraps.com/dotnetscraps/post/Run-a-batch-file-as-a-specific-User-(or-Administrator)-from-ASPNET.aspx

Thoughts on running Windows Service type apps on ASP .NET 4 with StartMode="AlwaysRunning"

Usually I would look at writing a Windows Service to manage tasks that aren't suited to being hosted in a web application. These types of tasks are usually long running processes or scheduled tasks. Although this is normally the primary approach for these types of tasks, people have looked at ways of running these kinds of background processes in a web application by kicking off a number of threads in the Application_Start event exposed by Global.asax. The problem with this approach has always been that if your IIS worker process dies, then your background thread is killed too (effectively your 'Windows Service' is stopped until the next request is received).
ASP .NET 4.0 offers a solution to this problem. You can now set the StartMode to 'AlwaysRunning' as described in this blog post by Scott Gu. Somewhere in the comments on this post, someone asks a question about the viability of hosting Windows Service type tasks in IIS since the new feature ensures the worker process is always running. Scott mentioned that it would definitely support the scenario. Further to this, the recent introduction of AppFabric means that Microsoft themselves are providing simple hooks for hosting and monitoring WCF and WF services in a web application.
What does this mean for those of us that used to write Windows Services to support our web apps? Should we adopt this model? What are the pitfalls? As far as I can tell, there are a number of benefits to hosting 'Windows Service' processes in a web application, the most useful being the ease of deployment. Furthermore, we can actually start developing simple user interfaces to our services which provide information about what is happening at runtime.
If I had to go this route, I don't think that I would host my 'Windows Service' type functionality in the customer facing web application. I would probably develop a new web application project (much like I would in the Windows Service context) that would host my long running/scheduled task processes. I guess there are few reasons for this.
Security. There may be a different security model for the UI displaying information about the running background processes. I would not want to expose this UI to anyone else but the ops team. Also, the web application may run as a different user which has an elevated set of permissions.
Maintenance. It would be great to be able to deploy changes to the application hosting the background processes without impacting on user's using the front end website.
Performance. Having the application separated from the main site processing user requests means that background threads will not diminish IIS's capability to handle the incoming request queue. Furthermore, the application processing the background tasks could be deployed to a separate server if required.
I would be really interested to hear your thoughts on this approach and whether I should be sticking with Windows Services. I am very tempted to try this new approach.
What does this mean for those of us that used to write Windows Services to support our web apps?
I think this a key scenario where you could be move away from a Windows service to using the continous running web site.
Should we adopt this model?
Standard development answer: Depends ;)
What are the pitfalls?
One issue I can see is the IIS dependency. If you need a service to run on a users machine I would not feel comfortable about asking them to install IIS just to run my service. Here I think the traditional model works better.
Monitoring and tracking are major issues, but as you also point out this is solved by AppFabric. It is even better than what you get from the Window Service. However you have added another dependency which also will require .NET 4.0 and a relatively new version of Windows. I could also be wrong here, but my understanding is that AppFabric is not supported in production on client OS's. Which could bring in additional headaches.
You will lose pause functionality in the continuous web site model too.
Finally IIS killing inactive app-pools isn't the only way an app pool can recycle. Editing a web.config file causes it for instance, which may not be an ideal situation.
the most useful being the ease of deployment.
I also think development is much easier - in the past I have had a console app and a windows service so I can dev/test on my machine using the console app and then change it to a windows service when it goes out. Now dev/test is MUCH easier.
A must read for this is Death to Windows Services...Long Live AppFabric!
What are the pitfalls?
One I found, no shutdown event. You have AppStart when the web site starts (not global.asax because that is HTTP only) but you have no way to handle shutdown which could mean disposing becomes an issue.
I would suggest sticking with a windows service. The issue is with your number 2.
You won't be able to update service part of web site without restarting whole web site.

Resources