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.