开发者

Detecting when an ASP.NET application recycles

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?


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.


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.


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();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜