2008-11-16 10 views
6

¿Es posible detectar un evento de reciclaje en el archivo global.asax?IIS Recycle Global.asax

Sé que el Application_End se activará, pero ¿hay alguna forma de saber que fue desencadenado por un reciclaje del grupo de aplicaciones?

THX, Lieven Cardoen aka Johlero

+0

Aplicación de reciclaje puede ser un asunto muy brutal en función del estado de su proceso - peor escenario es Win32 :: TerminateProcess que se llama. No hay forma de atrapar tal resultado en su proceso. ¿Qué estás intentando lograr? Enjuagar un poco el estado? – stephbu

Respuesta

3

Entonces, aquí hay una idea de cómo podría funcionar esto.

basa en mi previous answer (adjuntar a AppDomain.CurrentDomain.ProcessExit) y comentario stephbu 's:

Esto atrapará proceso más estructurado desmontajes por ejemplo, - pero no estoy seguro de que atrape todas las roturas. p.ej. http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx Reciclaje de proceso matará el proceso si parece estar bloqueado - no se llamó a su controlador .

que sugieren siguiente estrategia:

En el controlador (regular) ProcessExit (que suponemos no será anunciado en un grupo de aplicaciones de reciclaje), escribir algún archivo en el disco como "app_domain_end_ok.tmp".

Luego, en el Application_Start de su global.asax, busque este archivo. Si no existe, es una señal de que la aplicación no finalizó de forma limpia (o de que es la primera vez que se inicia). No olvides eliminar este archivo del disco después de la verificación.

No lo intenté yo mismo, pero podría valer la pena intentarlo.

+0

Gracias @splattne por el crédito ... – stephbu

+0

No he validado esto, pero sospecho que el reciclador de procesos tiene dos estrategias: 1) terminar el proceso de señalización y esperar mientras sondea para la salida del proceso; debería desencadenar ProcessExit en condiciones normales. 2) En tiempo de espera de espera, matar PID. – stephbu

1

nunca he intentado esto mismo, pero se puede tratar de conectar un controlador de eventos para el evento ProcessExit del dominio de aplicación.

... 
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnExit); 
... 

void OnExit(object sender, EventArgs e) { 
    // do something 
} 

Espero que esto ayude!

+0

Esto atrapará la mayoría de los desmantelamientos de procesos estructurados, p. - pero no estoy seguro de que atrape todas las roturas. p. http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx El proceso de reciclaje matará el proceso si parece estar bloqueado: no se llamará a su controlador. – stephbu

6

He encontrado este artículo en el blog de de Scott Guthrie:

Logging ASP.NET Application Shutdown Events

Alguien en una lista de correo electrónico recientemente pidió si había una manera de averiguar qué y cuando ASP.NET se reinicia dominios de aplicación. En concreto, buscaba la causa exacta de lo que se les desencadenando en su solicitud en un entorno alojado producción compartida (que era un cambio de archivo web.config , un cambio global.asax , un cambio de directorio App_Code, un cambio de eliminación de directorio, número máximo de compilaciones alcanzó cuota, \ bin cambio de directorio, etc.).

Thomas en mi equipo tiene un lugar fresco código fragmento que escribió que los usos algunos trucos ingeniosos reflexión privadas para capturar y registrar esta información. Es bastante fácil de reutilizar y añadir en cualquier aplicación, y se puede utilizar para registrar la información en cualquier lugar que falta (el siguiente código utiliza el NT Evento registro para guardarlo - pero podría ser tan sólo facilidad enviarlo a una base de datos o a través de un correo electrónico a un administrador). El código funciona con ASP.NET V1.1 y ASP.NET V2.0.

sólo tiene que añadir System.Reflection y System.Diagnostics espacios de nombres a su clase /archivo Global.asax, a continuación, agregue el evento Application_End con este código:

public void Application_End() { 

    HttpRuntime runtime = 
     (HttpRuntime) typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime", 
      BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, 
      null, null, null); 

    if (runtime == null) 
     return; 

    string shutDownMessage = 
     (string) runtime.GetType().InvokeMember("_shutDownMessage", 
      BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, 
      null, runtime, null); 

    string shutDownStack = 
     (string) runtime.GetType().InvokeMember("_shutDownStack", 
      BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, 
      null, runtime, null); 

    if (!EventLog.SourceExists(".NET Runtime")) { 
     EventLog.CreateEventSource(".NET Runtime", "Application"); 
    } 

    EventLog log = new EventLog(); 
    log.Source = ".NET Runtime"; 

    log.WriteEntry(String.Format(
      "\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}", 
      shutDownMessage, shutDownStack), 
     EventLogEntryType.Error); 
} 
0

yo era mucho más exitoso al unirse al evento DomainUnload, se desencadena en el reciclaje y la detención de AppPool de la propia AppPool.

AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;

Cuestiones relacionadas