检测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事件只触发一次。
我如何检测每次池/应用程序回收?
下面的代码可能有点复杂,但是您可以使用应用程序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();
}