2008-11-16 25 views
6

Est-il possible d'intercepter un événement de recyclage dans global.asax?IIS Recycle Global.asax

Je sais que Application_End sera déclenchée mais y a-t-il un moyen de savoir qu'elle a été déclenchée par un recyclage du pool d'applications?

thx, Lieven Cardoen alias Johlero

+0

App recyclage peut être une affaire assez brutale en fonction de l'état de votre processus - le pire scénario est Win32 :: TerminateProcess appelé. Il n'y a aucun moyen de piéger un tel résultat dans votre processus. Qu'essayez-vous d'accomplir? Flushing un état? – stephbu

Répondre

3

Donc, voici une idée de comment cela pourrait fonctionner.

Basé sur mon previous answer (joindre à AppDomain.CurrentDomain.ProcessExit) et commentaire de stephbu:

Ce piégera processus le plus structuré démontages par exemple - mais je ne suis pas sûr que ça va piéger tous les démontages. par exemple. http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx Processus de recyclage va tuer le processus s'il semble être accroché - votre gestionnaire ne serait pas appelé.

Je propose la stratégie suivante:

Dans le gestionnaire (régulier) de ProcessExit (que nous supposons ne sera pas fait appel à un pool d'applications de recyclage), écrire du fichier sur le disque comme « app_domain_end_ok.tmp ».

Puis, dans le fichier Application_Start de votre fichier global.asax, recherchez ce fichier. S'il n'existe pas, c'est un signe que l'application n'a pas été terminée de manière propre (ou que c'est la première fois qu'elle a commencé). N'oubliez pas de supprimer ce fichier du disque après la vérification.

Je n'ai pas essayé cela moi-même, mais ça pourrait valoir le coup d'essayer.

+0

Merci @splattne pour le crédit ... – stephbu

+0

Je n'ai pas validé cela mais je soupçonne que le recycleur de processus a deux stratégies - 1) le signal termine le processus et attend pendant l'interrogation de sortie du processus - il doit déclencher ProcessExit dans des conditions normales. 2) Au moment de l'attente, tuez le PID. – stephbu

1

Je ne l'ai jamais essayé moi-même, mais vous pouvez essayer de joindre un gestionnaire d'événements à l'événement ProcessExit du AppDomain.

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

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

J'espère que cela aide!

+0

Ceci piégera la plupart des démontages de processus structurés, par ex. - mais je ne suis pas sûr que ça va piéger tous les démontages. par exemple. http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx Le processus de recyclage va tuer le processus s'il semble être bloqué - votre gestionnaire ne serait pas appelé. – stephbu

6

Je trouve cet article sur Scott blog de Guthries:

Logging ASP.NET Application Shutdown Events

Quelqu'un sur une liste de diffusion a récemment demandé s'il y avait un moyen de comprendre pourquoi et quand ASP.NET redémarre domaines d'application. Plus précisément, il cherchait la cause exacte de ce qui les déclenche sur sa demande dans une production partagée environnement hébergé (était-il un changement de fichier web.config, un changement global.asax , un changement de répertoire App_Code, un changement de suppression de répertoire, max-num-compilations atteint quota, \ changement de répertoire bin, etc).

Thomas sur mon équipe a un frais bout de code qu'il a écrit que les utilisations quelques tricks de réflexion privés astucieuses pour capturer et enregistrer ces informations. Il est assez facile de réutiliser et d'ajouter dans une application, et peut être utilisé pour enregistrer les informations où vous besoin (le code ci-dessous utiliser l'événement NT le journal pour enregistrer - mais vous pouvez aussi facilement envoyez-le à une base de données ou via un e-mail à un administrateur). Le code fonctionne avec ASP.NET V1.1 et ASP.NET V2.0.

ajouter simplement le System.Reflection et System.Diagnostics à votre namespaces classe/fichier Global.asax, puis ajouter l'événement Application_End avec ce code :

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

J'étais beaucoup Plus réussi avec attachement à l'événement DomainUnload, il est déclenché sur le recyclage AppPool et l'arrêt de l'AppPool lui-même.

AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;