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

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

Как я могу сохранить это - или как я могу очистить это, когда приложение ASP.NET закрывается?

благодарю вас

Ответы на вопрос(4)

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

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

Решение Вопроса

Global.asax

void Application_End(object sender, EventArgs e) 
    {
        //  SHUTDOWN CODE HERE
    }

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

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

Грязный путь

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

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) Отмена регистрации (источник)

Сначала вызывается метод Stop с непосредственным параметром, для которого установлено значение 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 функциональность.

 Alexei18 июн. 2018 г., 15:48
@vladimirkhozeyev - действительнодокументация говорит, что: «Если непосредственный параметр имеет значение true, зарегистрированный объект должен вызвать метод UnregisterObject перед возвратом; в противном случае его регистрация будет удалена менеджером приложения». Если я правильно понимаю, забыть об отмене регистрации не должно быть проблемой, так как IIS должен вмешаться и отменить регистрацию в любом случае.
 vladimir khozeyev17 июн. 2018 г., 09:46
Спасибо за вашу ссылку на IRegisteredObject! Но я обнаружил, что «немедленный» флаг означает «true, чтобы указать, что зарегистрированный объект должен быть отменен из среды хостинга». Поэтому я думаю, что лучше сделать некоторые проверки и выполнить HostingEnvironment.UnregisterObject () перед возвратом.

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

 Himberjack18 янв. 2011 г., 12:47
да, хорошо, эти случаи я не могу контролировать. Я хочу контролировать то, что я знаю и имею ...
 user286474006 июл. 2017 г., 22:56
Более «общий край» заботится оизящный выключение, например очистка журналов, без непредвиденных. Пулы приложений могут использоваться довольно часто (и для большой среды с большим количеством пулов это означает, что может быть много потерянных событий «общего случая»).
 djeeg18 янв. 2011 г., 12:51
если вы не заботитесь о том, чтобы пропустить эти крайние случаи, то вы можете не беспокоиться об обработке изящного завершения работы приложения. просто сделайте это частью ваших предположений приложения

Ваш ответ на вопрос