[英]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. 我试图检测由于修改了web.config文件或手动回收IIS应用程序池而导致ASP.NET应用程序何时回收。
Initially I thought ASP.NET's Application_End method would work, and tried the following: 最初,我认为ASP.NET的Application_End方法可以工作,并尝试了以下方法:
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. 该文件是在首次更改web.config文件时创建的,但是随后的更改并未触发该事件。 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.
同样,在IIS中进行测试时,第一个手动的应用程序池回收创建了文件,但后来的文件池没有创建文件-好像Application_End事件仅触发一次。
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. 以下内容可能有点破译,但是您可以使用应用程序
Cache
来解决。 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: 在基本页的
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
}
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. Application_Start
是执行此操作的最可靠的方法,但是它遭受与hack相同的问题,事实是它在第一次请求回收后发生。
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. 要跟踪应用程序池回收,您需要实现IRegisteredObject接口,调用ApplicationManager.CreateObject创建对象的实例,然后在应用程序启动期间向HostingEnvironment.RegisterObject注册它。
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. 当使用false作为参数调用此对象的IRegisteredObject.Stop(bool)实现时,这是通知应用程序域正在关闭,并且该对象应通过调用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.
调整计时器作业的频率以提高确定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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.