When exactly does the Application_End fire in the case of a WebService ??
I read (Application_End global.asax) that the Application_End is called everytime the application is unloaded. Does this mean after every call to a method in a web service ?
I have a piece of code that I need fired only once on the first call to the IIS, and again after the last call to the IIS (and between recycles), and I can't have it being fired upon every WebService request and response...
Application_End is exactly what you are looking for; The application is unloaded according to the configuration you set, but by default it will continue running for a certain amount of time of being idle after any requests come in, or it will remain running while requests are continually coming in.
Note that other things can cause the App Pool to refresh, and therefore cause Application_End to be called; a certain number of recompiles (due to changed aspx files, etc), a certain time period running, a certain amount of memory pressure, etc. Again, these are all configurable, but are set to reasonable defaults, generally.
The key thing to keep in mind is that you can expect there to be some time between Application_Start and Application_End, but you can't know how much time there will be, based on what is happening on the server.
Also note that when an App Pool is recycled, already-running requests are not stopped suddenly, and they may in fact overlap with new requests being handled by the new process. This means that an old app pool's End might be called after the new app pool's Start. But this should not matter, because each app has it's own AppDomain, and doesn't share data. (but sometimes that can explain otherwise weird behavior.) Oh, and finally; even that is configurable, too!
EDIT: One more thing to add! Note that if the server is taken down suddenly, Application_End would not be called.
Related
We are dealing with a problem of an application restarting too often (once every couple of hours). This results in the first visitor having a long load time every few hours. Furthermore, we have a separate server that handles queued messages, it may be down for a day without us knowing because the application will exit for no apparent reason.
Is there any event or method we could hook into to log when the application exits, why it exits, and possibly instruct it to restart?
IIS will shut down any app pool that is idle for a period of time. IIS will also recycle the app pool when it detects certain kinds of errors, etc...
You can certainly hook into the Application_End() event, however it is not guaranteed that this will be called in all cases. For instance, if the app is forcefully terminated it will not get called.
In more recent versions of IIS, you can configure IIS to keep your app "warm". You can also create a scheduled job that just touches your homepage every so often.
I believe what you're looking for is application_end, which gets fired when your IIS pool is recycled, or the application gets unloaded. Applications reload themselves when a required file changes as well.
I would like to fire a method 'ProcessBatch () ' to run every 'x' minutes when an ASP.Net app starts up.
I think I will have to add code for this to Application_Start event.
What is the best way of doing this, so that when the website has its app pool recycled then the scheduled task that is running is treated as a web request and allowed to complete?
You cannot create a scheduled task that runs "every x minutes" on a web server.
Some people write services that run on a client computer which pings the site every now and then. But for that you need that client to be up-and-running.
One workaround is, like you say, the Application_Start event, but your application may run longer than just a few minutes. We do not actually know when that is.
You could run your task someplace else, like the Session_Start event (whenever a new user opens one of your pages), or even the BeginRequest event if you write your own HttpModule.
In those events, you could remember the time the task was run for the last time (like a static, or in the ApplicationState maybe) to keep it from running hundreds of times per minute once your site has a huge load of users.
Hope this helps?
Also, depending on where your site is hosted, you may be able to use that provider's scheduled-task system. Azure has one, RackspaceCloud and DiscountASP.NET as well.
I have an ASP.NET Web Service (SOAP style) that is running in our production environment.
Our server guys have set things up such that things like starting and stopping of Windows services, etc., are sent via email to the appropriate parties.
Lately my boss has been getting emails about my ASP.NET web service:
The (My Web Service's Name) Application_Start method was called
Now I figure that what's happening here is that the service has gone so long since being called last that the server has unloaded it from memory and now it's being re-loaded again (the product that consumes this web service has declined in popularity, so this isn't too far fetched a theory).
However my boss tells me he's been getting this email "dozens" of times per day.
I suppose it's still possible that my theory above is accurate, especially given how it's spread out over 3-4 servers in our web tier, but is there any other explanation for why this might be happening so frequently?
At this point in time I don't know whether or not Application_End calls are being similarly emailed or not, or what the ratio is.
The application could be downloaded when some of the settings in <processModel> are exceeded. idleTimeout could be the one in your case, but also requestLimit and memoryLimit.
Also, and this is based on a true story, if you start any thread, run anything in a separate threadpool thread, or use the TPL, make sure that you catch any exception that might be thrown. Uncaught exceptions from those threads will kill the worker process. Check the application logs in the Windows event log. If this is the case, you should see the red icon application error signs around the same time that the emails go out.
I am trying to "log" forcefully when a user has been inactive and or the session has ended (either by inactivity or more importantly, when the browser has closed).
I dont want to use any silly AJAX solution to perform a post every few minutes for "im alive" or call when the browser is closed.
I was under the impression that if you store an object in Session, and you reach the Session_End event, then you will not be able to gain access to anything stored in Session as its ended.
But from some testing I have done, it appears that this is probably the last chance you can obtain access to the object.
Could this be true? is it reliable?
using ASP.NET 4.0 here.
Typically there are two things done.
The first is that a javascript timer is added to the client, not as a heartbeat, but rather as a reminder. If they are close to the session ending, then it simply says "session is about to end. Are you still there?" If so, then it does the "silly" post to ensure the server keeps the session going. This is purely to be nice to your users.
The second (and point of your question) is that you put something in session_end in order to clean up the session. Reliable? well.. most of the time.
Session_End won't run if the app pool is recycled. However, assuming the app pool is ok then yes it will execute when the session expires. The app pool can be recycled for a LOT of reasons ranging from the app crashing to exceeded memory usage to simply because it's been a while since the last reset. This is configurable in IIS.
Would I trust session_end? No. Not 100%. Of course, I wouldn't put anything inside of a session object that would require me to trust it 100% anyway.
For logging the timeout You can use the Global events to log at timeout. See this link for order of events http://www.techrepublic.com/article/working-with-the-aspnet-globalasax-file/5771721
when I access any page of my ASP.NET MVC website first time, then this first request is slow. It needs about 4-5 seconds to load. But every following request to any page is fast.
When I wait some minutes or a hour then every first request is slow again. Every following request is fast.
I think that IIS 7 is compiling the code and keep it in memory. After some time it will delete it from memory so it needs to compile it again.
What can I do that every first request is as fast as every following request?
(Without precompiling my source, if possible)
Thank you very much in advance!
If this is a production server then why not try adding a website monitor; such as up time robot. It basically asks for your websites headers and gets status codes like "200-ok", "404-not found", etc. every 5 minutes. This way your site is always spun up and does not impact log files/analytics as only headers are requested. I use this for my cloud sites as I find that they take 5 seconds to spin up which has an impact on site loading. With the monitor they are instant.
Oh and its free for up to 50 sites!
This could be the recycle worker processes setting on the application pool, check the value for that and either turn it off or make it longer.
Could also be the Shutdown worker process after being idle under performance for the application pool.
It's probably the second as that defaults to 20 minutes, the first one defaults to 29 hours I believe.
This is almost-certainly your app pool idle timeout setting (and not your code being recompiled).
The default app pool idle timeout in IIS is 20 minutes. Which means that, if 20 minutes pass and no requests come in to your app, IIS will shut down the worker process for your app pool, making your app "cold" again. Whoever makes the next request will be waiting several seconds as IIS restarts the worker process and "warms" your app back up.
If you don't want IIS to automatically "cool down" your app after a period of inactivity, you can disable the app pool idle timeout by setting it to 0.
Assuming that you have a regular stream of visitors, this should not be a problem in production. Also, unless you're physically altering any of your source files, IIS would not recompile it when it spins up your app.
Also, take a look at the .NET compilation settings available:
http://technet.microsoft.com/en-us/library/cc725812(WS.10).aspx
tl; dr
After quite extensive testing and gathering of relevant sources to attempt to resolve the issue, I think that the minimal solution may be (not verified) to add this code to the global.asax:
protected void Application_End()
{
...
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://web_domain.tld");
using (HttpWebResponse response = (HttpWebResponse)
request.GetResponse())
{
}
...
}
In the time of writing the post, this is used to effectevely maintain the site I worked on 'always-up' - with conjuction of setting the Idle Time-out (minutes) in IIS to 0 as mentioned in other answers. However I think that changing Idle Time-out (minutes) may not be necessary (assuming that Application_end event is raised when the switch of application pool to Idle mode occurs).
How it works (assuming it does):
There are 2 settings in the IIS application pool settings that affect when the application is suspended or terminated. One of them is Idle Time-out (minutes) which defaults to 20 minutes and when the specified time elapses since the last request, the worker process is suspended or terminated. When a next request comes, the worker process is resumed or started again and the Application_start event is raised (and so if the Application_start handler is defined in global.asax, it is executed). In case of the project I worked on, the Application_start took about 17 seconds to complete. So if the site was 'left alone' for 21 minutes and then the new request came, it took about a little more than 17 seconds before the response was sent back (Application_start + page processing). When another request was sent in the window of 20 minutes, the response was sent significantly faster (perhaps less than 1s), since the Application_start has already been processed.
Setting the Idle Time-out (minutes) value to 0 causes the worker process to never be suspended / terminated (at least due to the idle time - there may be another cause described below).
Apart from Idle Time-out (minutes), there is also the Regular time interval (minutes) setting in Recycling section of the IIS advanced settings. This defaults to 1740 minutes (29 hours) and is a regular scheduled task that causes the Application pool to periodically recycle (the period is fixed). This, I understood, is to prevent the accumulation of possible memory-leaks which, if present, may eventually crash the server by exhasting all the memory. The effect of app-pool recycling is that Application_end event is raised. However, after the application ends it is not automatically started again, so the Application_start event is not raised until an actual request comes (which is similar to the first case). So in the case of the aforementioned web application I worked on, it would again take about 17 seconds to process the first request to arrive after the recycling occured. Changing this value to 0 turns the recycling off, but I suppose that it is reasonable not to turn the recycling completely off due to the possibility of accumuluation of memory leaks over time (which may possibly even be caused by bugs in 3rd party libraries). I understand that the opinions differ on whether to set this value to 0 or not and may change over time.
Posible solution (without changing IIS settings):
If the requests are sent frequently enough, the app-pool may never switch to Idle mode. On the event of recycling, this would also cause to the application to start again. This can be achieved, for example, by using 3rd party service as described by #Rippo.
Proposed solution:
It has been observed that application pool recycling caused Application_end event to be raised. Assuming that it is also raised upon switching of the application pool to Idle mode, it would seem to be sufficient to create a request in the Application_end event handler to the website, which in both cases would then cause the application to start again (raising the Application_start event). The code is at the top of the answer.