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

本文关键字:应用程序 NET ASP 检测 | 更新日期: 2023-09-27 18:07:10

我正在尝试检测ASP。. NET应用程序由于web。正在修改配置文件或手动回收IIS应用程序池。

最初我认为ASP。. NET的Application_End方法可以工作,并尝试以下操作:

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

该文件是第一次创建web。配置文件已更改,但后续更改没有触发该事件。类似地,在IIS中测试时,第一次手动应用程序池回收创建了文件,但后面的几个没有——就好像Application_End事件只触发一次。

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

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

下面的代码可能有点复杂,但是您可以使用应用程序Cache来解决这个问题。每次页面加载时,您都可以检查缓存中的特定键,如果该键不存在,则可以将其视为"回收",然后添加该键。这不是最好的方法,但可能正好可以满足你的需要。

。在基本页面的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将是最可靠的地方做到这一点,但它遭受同样的问题与黑客的事实,它发生在第一个请求的回收后。

下面的堆栈溢出问题提供了这个问题的好答案:如何检测当前应用程序池是否正在结束

要跟踪应用程序池回收,你需要实现IRegisteredObject接口,调用ApplicationManager。创建对象的实例,然后将其注册到HostingEnvironment。

当这个对象的iregisteredoobject . stop (bool)实现以false作为参数被调用时,这是通知应用程序域被关闭,并且该对象应该通过调用HostingEnvironment.UnregisterObject来取消注册(有点像全局处置)。

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

你为什么不这样做呢?调整定时器作业的频率,以提高确定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();
}