Работает ли событие Application.ApplicationExit для получения уведомлений о выходе в приложениях, отличных от Winforms?

StackOverflow https://stackoverflow.com/questions/529867

Вопрос

Наша библиотека кода должна получать уведомление при выходе приложения.Итак, мы подписались на событие System.Window.Forms.Application.ApplicationExit.Это хорошо работает для приложений Winforms, но работает ли оно и для других типов приложений, таких как консольные приложения, службы и веб-приложения (например, ASP.NET)?Пространство имен предполагает, что это не так, и оно, по-видимому, возникает, когда Application.Exit() вызывается (явно или неявно), что может быть неправильным для вызова этих других случаев.

Есть ли какое-то другое событие, которое было бы лучше в этих случаях или которое было бы более универсальным (отлично, если оно работает и для Winforms)?Например, есть ли событие, когда Environment.Exit() называется (консольное приложение)?

Я нашел упоминание о событии Exited в System.Diagnostic.Process, но, похоже, оно предназначено для мониторинга выхода другой процесс, и он не кажется полученным процессом о себе (например, Process.GetCurrentProcess().Exited += Process_Exited; Process.GetCurrentProcess().EnableRaisingEvents = true;).Я думаю, что он может быть поднят только после фактического завершения процесса, так что это не сработает.

Это особенно актуально для .NET 2.0 и C#.

Это было полезно?

Решение

Наконец мы нашли больше об этом (но к тому времени моя машина была перестроена и потеряла файлы cookie моего незарегистрированного профиля здесь;надеюсь, это позволит мне опубликовать этот ответ).

Дальнейшее расследование в конечном итоге выявило еще несколько событий, которые мы сочли полезными:

System.Windows.Forms.Application.ThreadExit - Срабатывает при выходе из цикла сообщений.System.Windows.Forms.Application.ApplicationExit - Срабатывает при выходе из всех циклов сообщений.System.AppDomain.CurrentDomain.DomainUnload - Срабатывает, когда выходит домен, отличный от домена по умолчанию.System.AppDomain.CurrentDomain.ProcessExit - Срабатывает при выходе из домена приложения по умолчанию.System.AppDomain.CurrentDomain.UnhandledException - Срабатывает при возникновении неперехваченного исключения, завершающего работу приложения.

Только один из DomainUnload или ProcessExit события возможны для данного домена приложения, в зависимости от того, является ли он доменом по умолчанию (верхнего уровня) для процесса или был создан как поддомен (например.на веб-сервере).Если приложение не знает, что это может быть (как в нашем случае), ему необходимо подписаться на оба, если оно хочет перехватить фактическую выгрузку для себя.Кроме того, оказывается, что UnhandledException (что в .NET2.0 всегда фатально) может предотвратить два других события, так что это может быть третий случай, который нужно обработать.Эти три события должны работать для любого приложения .NET.

Есть оговорка, что время выполнения для ProcessExit ограничено (около 4 секунд?), поэтому в этом обработчике событий может быть невозможно выполнить обширную «окончательную» работу.Это должно быть что-то, что можно сделать быстро.

А Application события применяются только к приложениям WinForms (однако мы подозреваем, что они могут не применяться в чистых приложениях WPF).Именование может вводить в заблуждение, поскольку они названы в честь их основного нормального использования, которое предполагает определенные предположения. ThreadExit не имеет отношения к действительности System.Threading.Thread а скорее в цикл сообщений (Application.Run())) потока пользовательского интерфейса и ApplicationExit аналогично относится к сбору форм приложения в одном или нескольких потоках пользовательского интерфейса.Обычно после вызова Application.Run() возвращает, вызываемый из метода входа потока, метод входа быстро завершает работу, а затем завершается сам поток.И как только все потоки пользовательского интерфейса завершатся, приложение WinForms обычно завершает работу и завершает работу.

Еще одним примечательным событием является System.Windows.Forms.Application.ThreadException событие.Цикл сообщений Windows можно настроить для перехвата исключений, возникающих при обработке сообщения, и отправки этого события, а не для того, чтобы они были неперехваченными (и, следовательно, фатальными) исключениями.Перехват этих исключений позволяет циклу обработки сообщений (и этому потоку пользовательского интерфейса) продолжить работу (после прерывания текущего обработчика сообщений).В любой момент времени для данного потока может быть только один подписчик на это событие (подписки перезаписывают любого предыдущего подписчика), и его необходимо настроить до создания любой формы и подписки перед входом в цикл сообщений.См. справку MSDN для этого события и System.Windows.Forms.Applicaton.SetUnhandledExceptionMode() для получения дополнительной информации.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top