IIS Recycle Global.asax - PullRequest
       41

IIS Recycle Global.asax

7 голосов
/ 16 ноября 2008

Можно ли перехватить событие recycle в global.asax?

Я знаю, что Application_End будет запущен, но есть ли способ узнать, что он был вызван перезапуском пула приложений?

thx, Ливен Кардоен или Джохлеро

Ответы [ 4 ]

7 голосов
/ 19 ноября 2008

Я нашел эту статью в блоге Скотта Гатриса :

Регистрация событий отключения приложений ASP.NET

Кто-то из списка рассылки недавно спросил был ли способ выяснить почему и когда ASP.NET перезагружается домены приложений. В частности, он искал точную причину что вызвало их на его приложение в разделе продукции размещенная среда (это было изменение файла web.config, глобальный .asax изменение, изменение каталога app_code, изменение каталога удалить, достигнуто максимальное количество сборников, \ bin, изменение каталога и т. д.).

Томас в моей команде классный фрагмент кода, который он написал, который использует некоторые изящные частные уловки отражения захватить и записать эту информацию. Это довольно легко повторно использовать и добавить в любое приложение, и может быть использовано регистрировать информацию где угодно хочу (код ниже использует событие NT Журнал, чтобы сохранить его - но вы могли бы так же, как легко отправить его в базу данных или через написать админу). Код работает с ASP.NET V1.1 и ASP.NET V2.0.

Просто добавьте System.Reflection и Пространства имен System.Diagnostics для вашего Global.asax класс / файл, а затем добавить событие Application_End с этим код:

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);
}
3 голосов
/ 16 ноября 2008

Итак, вот идея, как это могло бы работать.

На основании моего предыдущего ответа (прикрепить к AppDomain.CurrentDomain.ProcessExit) и комментария stephbu :

Это заманивает в ловушку наиболее структурированный процесс например, демонтаж - но я не уверен, что это подстерегает все разрушения. например http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx Процесс перезапуска убьет процесс если кажется виснет - твой обработчик не позвонят.

Я предлагаю следующую стратегию:

В (обычном) обработчике ProcessExit (который, как мы полагаем, не будут вызываться при перезапуске пула приложений), запишите какой-нибудь файл на диск, например "app_domain_end_ok.tmp".

Затем в Application_Start вашего global.asax проверьте этот файл. Если это не существует, это признак того, что приложение не было завершено чистым способом (или это - первый раз, когда это запустилось). Не забудьте удалить этот файл с диска после проверки.

Я сам не пробовал, но это может стоить попробовать.

1 голос
/ 16 ноября 2008

Я никогда не пробовал это сам, но вы можете попытаться присоединить обработчик события к событию ProcessExit в AppDomain.

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

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

Надеюсь, это поможет!

0 голосов
/ 10 ноября 2016

Я был гораздо успешнее с подключением к событию DomainUnload, оно запускается при перезапуске AppPool и остановке самого AppPool.

AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;

...