2011-09-01 17 views
10

Estoy tratando de detectar cuándo se está reciclando una aplicación ASP.NET debido a que el archivo web.config se está modificando o el grupo de aplicaciones IIS se recicla manualmente.Detectando cuando una aplicación ASP.NET recicla

principio pensé método Application_End de ASP.NET funcionaría, y trataron los siguientes:

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

El archivo se creó la primera vez que el archivo web.config se cambió, pero los cambios posteriores No se disparó el evento. De forma similar, cuando se prueba en IIS, el primer reciclado de grupo de aplicaciones manual creó el archivo, pero los posteriores no lo hicieron, es como si el evento Application_End solo se activara una vez.

¿Cómo puedo detectar cada vez que el grupo/la aplicación se recicla?

+6

¿No puedes usar Application_Start incluso? Supongo que algunos eventos como el apagado o el corte de energía no te avisarán cuando se invocó Application_End. –

+1

¿Se aseguró de acceder a una página en la aplicación después de cambiar el archivo web.config, por lo que finalizó y luego comenzó de nuevo? Porque si nunca volvió a comenzar, pude ver que eso impedía que Application_End se disparara más tarde. – StriplingWarrior

Respuesta

4

Lo siguiente puede ser un poco un truco, pero puede usar la aplicación Cache para resolverlo. Cada vez que se carga una página, puede verificar la caché de una clave específica; si la clave no existe, puede considerarla como un "reciclaje" y luego agregar la clave. No es el mejor método, pero podría funcionar para lo que necesita.

Por ejemplo. En su página base Page_Load o en algún lugar que se ejecutará con cada solicitud, se puede hacer lo siguiente:

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 
} 

Este método no va a recogerlo como ocurre el reciclaje. Solo identificará un reciclaje en la primera solicitud después del reciclado.

El Application_Start sería el lugar más confiable para hacer esto, pero adolece del mismo problema que el truco con el hecho de que ocurre después del reciclado en la primera solicitud.

+1

¿Resuelve esto algo que 'Application_Start' no hace? – TheCodeKing

+0

@TheCodeKing No es por eso por lo que dije (fíjate en la última línea de mi respuesta) que el 'Application_Start' sería el mejor lugar. Solo si por alguna razón hubo problemas que provocan que 'Application_End' y' Start' no se activen, esta es una alternativa hacky. – Kelsey

+1

Es solo 'Application_Start' que ** siempre ** se llamará, es solo' Application_End' que no puede - en la aplicación de reciclaje, por ejemplo. – TheCodeKing

0

¿Por qué no haces algo como esto? Ajuste la frecuencia del trabajo del temporizador para aumentar la precisión a la hora de determinar cuándo se recicla el 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(); 
} 
2

La buena respuesta a esta pregunta fueron proporcionados en la siguiente pregunta desbordamiento de pila: how to detect if the current application pool is winding up

Para rastrear grupo de aplicación reciclaje es necesario implementar la interfaz IRegisteredObject, llame ApplicationManager.CreateObject para crear una instancia de su objeto y luego registrarlo con HostingEnvironment.RegisterObject durante el inicio de la aplicación.

Cuando se llama a la implementación de este objeto IRegisteredObject.Stop (bool) con el parámetro falso, esta es una notificación de que el dominio de la aplicación se está cerrando y que el objeto no debe registrarse (como un desecho global) con un llamar a HostingEnvironment.UnregisterObject.

Por lo tanto, con este evento puede realizar un seguimiento cuando se recicla el grupo de aplicaciones.

Cuestiones relacionadas