Обнаружение при повторном использовании приложения ASP.NET

Я пытаюсь обнаружить, когда приложение 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 срабатывало только один раз.

Как я буду обнаруживать каждый раз, когда пул/приложение перерабатывает?

Ответ 1

Ниже может быть немного взлома, но вы можете использовать приложение 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 будет самым надежным местом для этого, но он страдает от той же проблемы, что и взлом с тем фактом, что это происходит после повторного использования по первому запросу.

Ответ 2

Хороший ответ на этот вопрос был предоставлен в следующем вопросе: как определить, что текущий пул приложений завершается.

Чтобы отслеживать переработку пула приложений, вам необходимо реализовать интерфейс IRegisteredObject, вызвать ApplicationManager.CreateObject для создания экземпляра вашего объекта и затем зарегистрировать его с помощью HostingEnvironment.RegisterObject во время запуска вашего приложения.

Когда этот объект IRegisteredObject.Stop(bool) реализуется с параметром false, это уведомление о том, что домен приложения закрыт и что объект должен быть незарегистрирован (вроде как глобальный dispose) с вызовом в HostingEnvironment.UnregisterObject.

Итак, используя это событие, вы можете отслеживать, когда пул приложений перерабатывается.

Ответ 3

Почему бы вам не сделать что-то подобное. Отрегулируйте частоту задания таймера, чтобы повысить точность определения при повторном использовании 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();
}