11

I'm trying to detect when an ASP.NET application is recycling due to either the web.config file being modified or the IIS application pool being manually recycled.

Initially I thought ASP.NET's Application_End method would work, and tried the following:

protected void Application_End(object sender, EventArgs e)
{
    File.AppendAllText("log.txt", DateTime.Now + "\n");
}

The file was created the first time the web.config file was changed, but subsequent changes didn't fire the event. Similarly, when testing in IIS, the first manual application pool recycle created the file but later ones didn't - it's as if the Application_End event only ever fires once.

How would I detect each time the pool/app recycles?

2
  • 6
    Cant you use Application_Start even rather ? I guess some events like shutdown or power outage wont let you know when Application_End was called.
    – Pit Digger
    Commented Sep 1, 2011 at 14:25
  • 1
    Did you make sure you accessed a page in the application after changing the web.config file, so it ended and then started again? Because if it never started again, I could see that preventing the Application_End from firing afterward. Commented Sep 1, 2011 at 14:41

3 Answers 3

4

The following might be a little bit of a hack but you could use the application Cache to figure it out. Everytime a page loads you could check the cache for a specific key, if the key doesn't exist then you can consider it a 'recycle' and then add the key. Not the best method but might just work for what you need.

Eg. In your base page's Page_Load or somewhere that will run with every request, you could do the following:

if (HttpContext.Current.Cache["RecycleCheck"] != null)
{ 
    // Add flag to cache
    HttpContext.Current.Cache.Insert("RecycleCheck", "1", null,
        DateTime.UtcNow.AddDays(2),  // 2 days (most will recycle by then)
        System.Web.Caching.Cache.NoSlidingExpiration);

    // Do what you need because a recycle has happened
}

This method will not pick it up as the recycle happens. It will only identify a recycle on the first request after the recycle.

The Application_Start would be the most reliable place to do this but it suffers from the same issue as the hack with the fact that it happens after the recycle on the first request.

3
  • @TheCodeKing Not really by that is why I said (notice the last line of my answer) the Application_Start would be the best place. Only if for some reason there were issues cause the Application_End and Start to not trigger, this is a hacky alternative.
    – Kelsey
    Commented Sep 1, 2011 at 20:23
  • 1
    It's just Application_Start will always get called, it's only Application_End that may not - on app recycle for instance. Commented Sep 1, 2011 at 21:48
  • Application_End gets called on Recycle too. Not sure why you're suggesting it won't be.
    – Triynko
    Commented Mar 1, 2019 at 18:18
4

The good answer to this question were provided in the following stack overflow question: how to detect if the current application pool is winding up

To track app pool recycling you need to implement the IRegisteredObject interface, call ApplicationManager.CreateObject to create an instance of your object and then register it with HostingEnvironment.RegisterObject during your application start up.

When this object's IRegisteredObject.Stop(bool) implementation is called with false as the parameter, this is notification that the app domain is being shut down and that the object should be unregistered (kind of like a global dispose) with a call to HostingEnvironment.UnregisterObject.

So, using this event you can track when application pool is recycled.

0

Why don't you do something like this. Adjust the frequency of the timer job to increase the accuracy in determining when the appPool recycles.

private readonly Timer timer = new Timer();
private DateTime start;
private string logFile;

void Application_Start(object sender, EventArgs e)
{
  start= DateTime.Now;
  logFile = Server.MapPath(
            string.Concat("Log-",start.ToString("yyyyMMdd-HHmmss.fff"),".txt"));

  timer.Interval = 1000;
  timer.Elapsed += (s, ee) 
            => File.WriteAllText(logFile,
            string.Concat("App Start :", start, " Last Alive: ", DateTime.Now));

  timer.Start();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.