Как прослушать событие отключения IIS в ASP.NET - PullRequest
11 голосов
/ 18 января 2011

У меня есть статическая переменная ASP.NET, которая сбрасывает себя в БД каждые X вставок.Проблема в том, что если я опубликую приложение, процесс IIS будет уничтожен всеми моими статическими материалами.

Как я могу сохранить его или как его сбросить после завершения работы приложения ASP.NET?

спасибо

Ответы [ 4 ]

13 голосов
/ 18 января 2011

Global.asax

void Application_End(object sender, EventArgs e) 
    {
        //  SHUTDOWN CODE HERE
    }
7 голосов
/ 19 января 2017

Как уже говорилось, настоятельно не рекомендуется, чтобы приложение сохраняло большие данные во время Application_End, так как это может быть вызвано, когда пул приложений выключен, а не в начале его выключения.Это объясняется более подробно (но все еще кратко) здесь .

Если кто-то все еще хочет поймать завершение работы пула приложений для всех случаев, которые не уничтожают его немедленно, можно выполнитьследующее:

Грязный путь

1) Получить ограничение по времени выключения - диспетчер IIS -> Пулы приложений -> -> Расширенные настройки ... -> Группа моделей процесса-> Ограничение времени выключения (секунда)

2) Создайте поток / задачу в приложении, чтобы запускать его вдвое чаще, чем ограничение времени выключения, чтобы обеспечить возможность захвата состояния «выключения».Этот поток должен

i) проверить, закрывается ли пул приложений

public bool IsShuttingDown()
{
    return System.Web.Hosting.HostingEnvironment.ShutdownReason != ApplicationShutdownReason.None;
}

ii) если выключение включено, сделайте свое дело.Убедитесь, что материал выполняется только один раз

Более правильный путь (как указано здесь )

1) Создайте класс, который реализует IRegisteredObject

public class HostingEnvironmentRegisteredObject : IRegisteredObject
{
    // this is called both when shutting down starts and when it ends
    public void Stop(bool immediate)
    {
        if (immediate)
            return;

        // shutting down code here
        // there will about Shutting down time limit seconds to do the work
    }
}

2) Зарегистрировать ваш объект (Global.asax.cs)

protected void Application_Start()
{
    // other initialization code here

    HostingEnvironment.RegisterObject(new HostingEnvironmentRegisteredObject());
}

3) Отменить регистрацию ( источник )

СтопМетод сначала вызывается с непосредственным параметром, установленным в false.Объект может либо завершить обработку, вызвать метод UnregisterObject и затем вернуться, либо он может сразу же вернуться и завершить обработку асинхронно перед вызовом метода UnregisterObject.

Если зарегистрированный объект не завершает обработку до времени менеджера приложений,истекает период истечения, метод Stop вызывается снова с непосредственным параметром, установленным в true.Если непосредственный параметр имеет значение true, зарегистрированный объект должен вызвать метод UnregisterObject перед возвратом; в противном случае его регистрация будет удалена диспетчером приложений.


Какпримечание, я также включу некоторые подробности о реализации той же идеи в ASP.NET Core 2.x.Это может быть выполнено с использованием интерфейса IApplicationLifetime .Пример (Startup.cs):

public void Configure(IApplicationLifetime lifetime)
{
    var quartz = new JobScheduler(Kernel);
    lifetime.ApplicationStarted.Register(quartz.Start);
    lifetime.ApplicationStopping.Register(quartz.Stop);
}

Примечание. Это будет работать только в том случае, если оно размещено в IIS (возможно, на других веб-серверах), но не в IISExpress, который не будет запускать функциональность IApplicationLifetime.

6 голосов
/ 18 января 2011

Это рискованно полагаться на события завершения работы приложения, чтобы поддерживать базу данных обновленной.Если IIS принудительно перезапускается, перерабатывается или происходит сбой питания, вы пропустите событие.

3 голосов
/ 18 января 2011

Возможно, вы не получите никакого уведомления о завершении работы IIS.Подумайте, что произойдет, если IIS AppPool выйдет из строя, или что произойдет, если сервер просто отключится.

Вы не можете рассчитывать на то, что услышите о событиях выключения.Если IIS хочет завершить работу, он не обязательно уведомит вашу заявку.Я рекомендую вам пересмотреть свой сценарий буферизации записи / кэширования - храните в памяти только те данные, которые вы можете позволить себе потерять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...