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

发布于 2024-12-02 18:03:36 字数 429 浏览 6 评论 0原文

我试图检测 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 事件只触发一次。

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰魂雪魄 2024-12-09 18:03:36

下面的内容可能有点破解,但您可以使用应用程序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 将是执行此操作的最可靠位置,但它遇到与黑客相同的问题,因为它发生在第一个请求的回收之后。

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.

暖风昔人 2024-12-09 18:03:36

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

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

当使用 false 作为参数调用此对象的 IRegisteredObject.Stop(bool) 实现时,这是应用程序域正在关闭的通知,并且应该通过调用 HostingEnvironment 取消注册该对象(类似于全局处置)。取消注册对象。

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

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.

画中仙 2024-12-09 18:03:36

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

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

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文