Как обнаружить, что текущий пул приложений завершается в IIS7.5 и Asp.Net 3.5+

Ну, точно так же, как речь идет о субъектах вопроса - какие-нибудь идеи о том, как вы можете это сделать?

Я просматривал объекты в System.Web.Hosting, но ничего не выделяется.

Причина? Я получаю одну или две ошибки приложения, которые обычно возникают во время повторного использования (они происходят примерно через 25 часов, и я оставил время утилизации пула приложений по умолчанию), и поэтому я хочу знать, происходят ли они на поток, который в пуле, который выключается, или тот, который запускает (ed/ing) вверх.

Ответы

Ответ 1

Недавно я наткнулся на эту статью о Brain.Save(), в которой говорится именно об этой проблеме с точки зрения размещения WCF (он Стив Мейн - менеджер программ в Редмонде в подразделении подключенных сервисов).

Они должны иметь возможность сделать это, когда служба WCF размещается внутри Asp.Net, так как они должны иметь возможность выключать любые открытые слушатели, чтобы механизм WCF в новом домене приложения смог открыть их все еще раз.

Как показано в статье, ответ заключается в реализации интерфейса IRegisteredObject, вызывает ApplicationManager.CreateObject, чтобы создать экземпляр вашего объекта, а затем зарегистрировать он с HostingEnvironment.RegisterObject (все подробно описано в документации MSDN для интерфейса).

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

Когда он вызывается с помощью true, это означает, что вы не были незарегистрированы своевременно, и если вы не отмените регистрацию сразу, это будет сделано для вас.

Я могу, конечно, использовать этот механизм, чтобы узнать, когда возникает исключение, если AppDomain убит или нет. Характер объекта, который вызывает исключение, означает, что если он не при выключении, он должен быть при первом запуске.

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

История

В статье также объясняется некоторая история и обоснование того, почему вы хотели бы использовать методы IRegisteredObject, а не Application_Start и Application_End в global.asax:

Традиционные приложения ASP.NET могут перехватывать события жизненного цикла приложения (запуск/завершение работы приложения), реализуя такие методы, как Application_Start и Application_Stop в global.asax. Однако global.asax предназначен для кода приложения. Компоненты инфраструктуры (из которых система хостинга WCF одна) нуждаются в механизме подключения событий жизненного цикла AppDomain, которые не связаны с кодом демпинга инфраструктуры в файле global.asax. Это пространство зарезервировано для вас, для пользователя, и было бы грубо использовать загрязнение, что с кучей хостинга хоу мы должны заставить все это работать. Вместо этого, люди ASP.NET проделали большую работу во время выпуска Whidbey, чтобы открыть API-интерфейсы хостинга и упростить для людей, таких как WCF, и задействовать эти события жизненного цикла таким образом, который невидим для кода приложения.

Ответ 3

Добавление фактического кода для этого:

public class RecycleWatcher : IRegisteredObject
{
    public static bool IsRecycling { get; private set; }

    public void Register()
    {
        HostingEnvironment.RegisterObject(this);
    }
    public void Stop(bool immediate)
    {
        IsRecycling = true;
    }
}

Затем включите его, запустив

new RecycleWatcher().Register();

После этого достаточно проверить, что свойство IsRecycling знать, если вы повторно выполняете или нет.

if (RecycleWatcher.IsRecycling) DoSomething();

Ответ 4

Не уверен, что именно вы хотите сделать, когда пул приложений будет перезагружен, но если вы добавите обработчик нижестоящего в Global.asax, тогда код в нем будет запущен, когда приложение будет отключено.

 protected void Application_End(object sender, EventArgs e)
 {
 }