检测ASP.NET应用程序何时回收

时间:2011-09-01 14:22:17

标签: c# asp.net iis application-pool

我正在尝试检测ASP.NET应用程序何时回收,原因是要修改web.config文件或手动回收IIS应用程序池。

最初我认为ASP.NET的Application_End方法可行,并尝试了以下内容:

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

该文件是在第一次更改web.config文件时创建的,但后续更改未触发该事件。同样,在IIS中进行测试时,第一个手动应用程序池回收创建了该文件,但后来的文件没有 - 就像Application_End事件只触发一次一样。

每次池/应用程序回收时如何检测?

3 个答案:

答案 0 :(得分:4)

以下可能有点像黑客,但你可以使用应用程序Cache来解决它。每次加载页面时,您都可以检查特定键的缓存,如果该键不存在,则可以将其视为“循环”,然后添加密钥。不是最好的方法,但可能只适合您的需要。

EG。在您的基页Page_Load或每个请求都会运行的某个位置,您可以执行以下操作:

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
}

此方法不会在循环发生时将其取出。它只会在回收后的第一个请求中识别回收。

Application_Start将是最可靠的地方,但它遇到了与黑客相同的问题,因为它发生在第一次请求回收之后。

答案 1 :(得分:2)

以下堆栈溢出问题提供了对此问题的良好答案:how to detect if the current application pool is winding up

要跟踪应用程序池回收,您需要实现IRegisteredObject接口,调用ApplicationManager.CreateObject来创建对象的实例,然后在应用程序启动时将其注册到HostingEnvironment.RegisterObject。

当使用false作为参数调用此对象的IRegisteredObject.Stop(bool)实现时,这是通知应用程序域正在关闭,并且该对象应该是未注册的(有点像全局配置)并且有一个调用到HostingEnvironment.UnregisterObject。

因此,使用此事件可以跟踪应用程序池何时被回收。

答案 2 :(得分:0)

你为什么不做这样的事情。调整计时器作业的频率,以提高确定appPool回收时间的准确性。

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