Question

Is it possible to catch an recycle event in the global.asax?

I know Application_End will be triggered but is there a way to know that it was triggered by a recycle of the application pool?

thx, Lieven Cardoen aka Johlero

Was it helpful?

Solution

So, here is an idea how this could work.

Based on my previous answer (attach to AppDomain.CurrentDomain.ProcessExit) and stephbu's comment:

This will trap most structured process teardowns e.g. - but I'm not sure that it will trap all tear downs. e.g. http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx Process recycle will kill the process if it seems to be hung - your handler wouldn't get called.

I suggest following strategy:

In the (regular) ProcessExit handler (which we suppose will not be called on a application pool recycling), write some file to disk like "app_domain_end_ok.tmp".

Then in the Application_Start of your global.asax check for this file. If it doesn't exist it is a sign that the application was not terminated in a clean way (or that it is the first time ever it started). Don't forget to delete this file from disk after the check.

I didn't try that myself, but it could be worth a try.

OTHER TIPS

I found this article on Scott Guthries's blog:

Logging ASP.NET Application Shutdown Events

Someone on a listserv recently asked whether there was a way to figure out why and when ASP.NET restarts application domains. Specifically, he was looking for the exact cause of what was triggering them on his application in a production shared hosted environment (was it a web.config file change, a global.asax change, an app_code directory change, a directory delete change, max-num-compilations reached quota, \bin directory change, etc).

Thomas on my team has a cool code-snippet that he wrote that uses some nifty private reflection tricks to capture and log this information. It is pretty easy to re-use and add into any application, and can be used to log the information anywhere you want (the below code use the NT Event Log to save it – but you could just as easily send it to a database or via an email to an admin). The code works with both ASP.NET V1.1 and ASP.NET V2.0.

Simply add the System.Reflection and System.Diagnostics namespaces to your Global.asax class/file, and then add the Application_End event with this code:

public void Application_End() {

    HttpRuntime runtime = 
       (HttpRuntime) typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime",
          BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, 
          null, null, null);

    if (runtime == null)
        return;

    string shutDownMessage = 
       (string) runtime.GetType().InvokeMember("_shutDownMessage",
           BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField,
           null, runtime, null);

    string shutDownStack = 
       (string) runtime.GetType().InvokeMember("_shutDownStack",
           BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField,
           null, runtime, null);

    if (!EventLog.SourceExists(".NET Runtime")) {
        EventLog.CreateEventSource(".NET Runtime", "Application");
    }

    EventLog log = new EventLog();
    log.Source = ".NET Runtime";

    log.WriteEntry(String.Format(
          "\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}", 
          shutDownMessage, shutDownStack),
       EventLogEntryType.Error);
}

I've never tried this myself, but you could try to attach an event handler to the ProcessExit event of the AppDomain.

...
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnExit);
...

void OnExit(object sender, EventArgs e) {
    // do something
}

I hope this helps!

I was much more successful with attaching to DomainUnload event, it is triggered on AppPool recycle and stoppage of the AppPool itself.

AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top