Управление приложением - PullRequest
6 голосов
/ 24 ноября 2010

У нас есть консольное приложение .NET, которое имеет много потоков переднего плана. Если мы убиваем процесс с помощью диспетчера задач или запускаем killjob, kill из командной строки в windows, есть ли способ, которым мы можем изящно завершить работу приложения (добавив управляемый код в консольное приложение .net), что-то вроде наличия функции вызывается скажем TodoBeforeShutdown (), который удаляет объекты, закрывает все открытые соединения и т. д.

P.S. - Я прочитал другие темы, и все они предложили разные способы уничтожения процесса, а не мой конкретный вопрос, как лучше всего обрабатывать процесс завершения в управляемом коде .NET.

Заранее спасибо.

Ответы [ 2 ]

10 голосов
/ 24 ноября 2010

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

Когда вы завершаете процесс с помощью диспетчера задач, он вызывает функцию Win32 TerminateProcess, которая безоговорочно заставляет процесс (включая все принадлежащие ему потоки) завершиться. Выполнение всех потоков / процессов прекращается, а все ожидающие запросы ввода-вывода отменяются. Ваша программа фактически мертва. Функция TerminateProcess не вызывает последовательность выключения, предоставляемую CLR, поэтому ваше управляемое приложение даже не будет знать, что оно закрывается.

Вы предлагаете беспокоиться об удалении объектов всякий раз, когда завершается процесс вашего приложения, но здесь есть несколько моментов, на которые стоит обратить внимание:

  • Всегда старайтесь свести к минимуму количество урона, которое можно нанести. Утилизируйте ваши объекты как можно раньше, когда вы закончите с ними. Не ждите до позже. В любой момент, когда процесс вашей программы завершается, вы должны хранить только минимальное количество объектов вокруг, что оставит меньше возможностей для утечек.

  • Операционная система обычно очищает и освобождает большинство этих ресурсов (т. Е. Дескрипторы и т. Д.) После завершения.

  • Наконец, само собой разумеется, что завершение процесса таким образом является действительно исключительным условием - даже если утечка некоторых ресурсов, это ожидаемо . Вы не должны закрывать приложение таким образом, как если бы вы убивали необходимые системные процессы Windows (даже если это возможно при работе от имени администратора).

Если вы регулярно закрываете консольное приложение, вам нужно найти другой план .

2 голосов
/ 24 ноября 2010

Короче говоря: вы не можете!
Уничтожение процесса - это полная противоположность грациозному выходу.
Если вы используете Foreground Threads, отправка wm_exit не закрывает ваше приложение.Поскольку у вас есть консольное приложение, вы можете просто перенаправить ввод с консоли, чтобы отправить «выход» в ваш процесс.
Кроме того, я думаю, что вы можете изменить приложение на службу (вместо консольного приложения), это предложит вам точночто вы ищете -> интерфейс для грациозного выхода, основанный на встроенных инструментах / командах Windows.

...