Как успешно завершить процесс с

от admin

Как успешно завершить процесс с

Завершение работы процесса

Процесс выполняется до тех пор, пока не произойдет одно из нижеследующих событий:

  • Какой-либо поток процесса вызывает функцию ExitProcess . Она завершает работу всех потоков процесса.
  • Первичный поток процесса возвращает значение. Первичный поток может отменить завершение работы других потоков, при помощи явного вызова ExitThread перед возвратом своего значения. Один из оставшихся потоков может все еще вызвать ExitProcess , чтобы гарантировать, что все потоки завершили работу.
  • Последний поток процесса завершил работу.
  • Какой-либо поток вызывает функцию TerminateProcess с дескриптором процесса. Это завершает работу всех потоков процесса, без разрешения им, чтобы они очистили или сохранили данные.
  • Для консольных процессов, заданная по умолчанию функция обработчика вызывает ExitProcess , когда консоль получает сигнал CTRL+BREAK или CTRL+C . Все консольные процессы, связанные с консолью получают эти сигналы. Отсоединенные процессы и процессы GUI — не затрагиваются сигналами CTRL+C , или CTRL+BREAK . Для получения дополнительной информации, см. статью SetConsoleCtrlHandler .
  • Пользователь закрывает систему или заканчивает работу сессии. Используйте функцию SetProcessShutdownParameters , чтобы установить параметры выключения системы, типа того, когда процесс должен завершиться относительно других процессов в системе. Функция GetProcessShutdownParameters извлекает данные о текущем приоритете завершения процесса и других флажках завершения.

Когда процесс завершает работу, все потоки процесса немедленно завершают работу без шанса запустить дополнительный код. Это означает то, что процесс не выполняет код в блоках обработчика завершения работы. Для получения дополнительной информации, см. статью Структурная обработка особых ситуаций .

Функция GetExitCodeProcess возвращает значение состояние завершения процесса. В то время пока процесс выполняется, его состояние завершения является STILL_ACTIVE . Когда процесс заканчивает работу, его состояние завершения изменяется из STILL_ACTIVE в код выхода процесса. Код выхода является или значением, определяемым при вызове ExitProcess или TerminateProcess , или значением, возвращаемым функцией main или функцией WinMain процесса. Если процесс завершил работу в результате фатальной исключительной ситуации, код выхода является значением исключения, которое вызвало завершение. Кроме того, это значение используется как код выхода для всех потоков, которые выполнялись, когда произошла исключительная ситуация.

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

Открытые дескрипторы файлов или других ресурсов закрываются автоматически, когда процесс завершает работу. Однако сами объекты существуют до тех пор, пока все их открытые дескрипторы не закроются. Это означает то, что объект остается допустимым после того, как процесс закрывается, если другой процесс имеет его дескриптор.

Если процесс завершил работу при помощи ExitProcess , система вызывает функцию точки входа каждой связанной динамически подключаемой библиотеки ( DLL ) со значением, указывающим, что процесс отсоединяется от DLL . Динамически связываемые библиотеки ( DLL ) не уведомляются, когда процесс завершает работу при помощи TerminateProcess . Для получения дополнительной информации о DLL , см. в главе Динамически-подключаемые библиотеки .

Выполнение функций ExitProcess , ExitThread , CreateThread , CreateRemoteThread и CreateProcess переводится в последовательный режим в пределах адресного пространства. Применяются нижеследующие ограничения:

  • В ходе запуска процесса и DLL процедуры инициализации, могут быть созданы новые потоки, но они не начинают исполнение кода до тех пор, пока не закончена инициализация DLL для процесса.
  • Только один поток одновременно может в DLL инициализировать или отключить процедуру.
  • Функция ExitProcess не возвращает значения до тех пор, пока нет никаких потоков в их DLL , которые инициализируют или отключают процедуры.

Внимание! Функция TerminateProcess должна использоваться только в экстремальных обстоятельствах, так как она не дает возможности потокам очищать или сохранять данные и не уведомляет связанные с процессом DLL. Если Вам нужно иметь один процесс, который завершает другой процесс, то нижеследующие шаги обеспечивают лучшее решение этой проблемы:

  • Необходимо, чтобы оба процесса вызвали функцию RegisterWindowMessage для создания нестандартного сообщения.
  • Один процесс может завершить работу другого процесса, при помощи транслирования нестандартного сообщения, используя функцию BroadcastSystemMessage, как ниже указано:
  • Процесс, получающий нестандартное сообщение вызывает ExitProcess , чтобы завершить свое выполнение.

Обратите внимание! , когда система завершает работу процесса, она не прерывает, какой-либо дочерний процесс, который этот процесс создал.

Функция exit

Функция exit выполняет немедленное завершение программы. Завершаемый процесс, как правило, выполняет очистку используемой памяти. Во-вторых, все функции, зарегистрированные вызовами atexit , выполняются в порядке, обратном порядку их регистрации. В таком случае, все используемые программой потоки закрываются, и временные файлы удаляются, и, наконец, управление возвращается ОС или другой программе.

Аргумент параметра value возвращается принимающей стороной (ОС или другой программой).

Справочник по C#

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

Завершение работы процесса

  • Пример №1 – использование метода «Kill» из класса «System.Diagnostics»;
  • Пример №2 – завершение процессов по идентификаторам или именам исполняемых файлов на локальной или удаленной системе с использованием команды «TASKKILL»;
  • Пример №3 – использование Windows API функции «TerminateProcess» из библиотеки «Kernel32.lib».

Пример №2

Данный пример описывает завершение процессов по идентификаторам или именам исполняемых файлов на локальной или удаленной системе с использованием команды «TASKKILL». Команда может использоваться в операционных системах Windows XP и старше.

  • /F — Принудительное завершение процесса.
  • /IM <имя процесса> — Имя образа процесса, который требуется завершить. Знак подстановки «*» может быть использован для указания всех заданий или имен образов.
  • /T — Завершение указанного процесса и всех его дочерних процессов.
  • TASKKILL /IM notepad++.exe — завершение процесса, исполняемым образом которого является notepad.exe++. Если таких процессов более одного — то будут завершены все;
  • TASKKILL /PID 1568 /T — завершить процесс с идентификатором 1568 и все его дочерние процессы (/T) . Одной командой можно завершить несколько процессов, задавая их PID — taskkill /PID 1568 /PID 1569 /PID 1570;
  • TASKKILL /F /FI «PID ge 2015» /FI «WINDOWTITLE eq Arc*» — принудительно (/F) завершить процесс, идентификатор которого больше или равен 2000 и заголовок окна которого , начинается с текста Arc;
  • TASKKILL /F /FI «USERNAME eq NT AUTHORITY\SYSTEM» /IM notepad++.exe — принудительно завершить процесс, выполняющийся в контексте учетной записи NT AUTHORITY\SYSTEM и исполняемый файл которого имеет имя notepad.exe++;
  • TASKKILL /S 192.168.1.105 /U MyDomain\user /FI «USERNAME ne NT*» /IM * — завершить все процессы, выполняющиеся в контекстах учетных записей, не начинающихся со строки NT на компьютере с IP-адресом 192.168.0.243. При подключении к удаленной системе используется имя пользователя user в домене Mydomain. Пароль не задан и будет запрошен при выполнении команды;
  • TASKKILL /S SERVER /U Mydomain\User /P UserPass /FI «IMAGENAME eq note*» — завершить все процессы, имя исполняемого файла которых начинается со строки note на удаленном компьютере с именем SERVER.
Читать:
Gradle что за папка

В данном примере для завершения работы процесса используется Windows API функция «TerminateProcess» из библиотеки «Kernel32.lib». Функция не дает процессу ни малейшего шанса самому провести очистку, операционная система высвобождает все принадлежавшие ему ресурсы: возвращает себе выделенную им память, закрывает любые открытые файлы, уменьшает счетчики соответствующих объектов ядра и разрушает все его User- и GDI-объекты.
После завершения процесса система гарантирует: после него ничего не останется — даже намеков на то, что он когда-то выполнялся. Завершенный процесс не оставляет за собой никаких следов. Синтаксис данной функции представлен ниже.
Параметр «hProcess» идентифицирует описатель завершаемого процесса, а в параметре «uExitCode» возвращается код завершения процесса.

Как успешно завершить процесс с

Параллельное выполнение задач может занимать много времени. И иногда может возникнуть необходимость прервать выполняемую задачу. Для этого платформа .NET предоставляет структуру CancellationToken из пространства имен System.Threading .

Общий алгоритм отмены задачи обычно предусматривает следующий порядок действий:

Создание объекта CancellationTokenSource , который управляет и посылает уведомление об отмене токену.

С помощью свойства CancellationTokenSource.Token получаем собственно токен — объект структуры CancellationToken и передаем его в задачу, которая может быть отменена.

Для передачи токена в задачу можно применять один из конструкторов класса Task:

Определяем в задаче действия на случай ее отмены.

Вызываем метод CancellationTokenSource.Cancel() , который устанавливает для свойства CancellationToken.IsCancellationRequested значение true. Стоит понимать, что сам по себе метод CancellationTokenSource.Cancel() не отменяет задачу, он лишь посылает уведомление об отмене через установку свойства CancellationToken.IsCancellationRequested . Каким образом будет происходить выход из задачи, это решает сам разработчик.

Класс CancellationTokenSource реализует интерфейс IDisposable. И когда работа с объектом CancellationTokenSource завершена, у него следует вызвать метод Dispose для освобождения всех связанных с ним используемых ресурсов. (Вместо явного вызова метода Dispose можно использовать конструкцию using).

Теперь касательно третьего пункта — определения действий отмены задачи. Как именно завершить задачу? Конкретные действия на лежат целиком на разработчике, тем не менее есть два общих варианта выхода:

При получении сигнала отмены выйти из метода задачи, например, с помощью оператора return или построив логику метода соответствующим образом. Но следует учитывать, что в этом случае задача перейдет в состояние TaskStatus.RanToCompletion , а не в состояние TaskStatus.Canceled .

При получении сигнала отмены сгенерировать исключение OperationCanceledException , вызвав у токена метод ThrowIfCancellationRequested() . После этого задача перейдет в состояние TaskStatus.Canceled .

Мягкий выход из задачи без исключения OperationCanceledException

Сначала рассмотрим первый — «мягкий» вариант завершения:

В данном случае задача task вычисляет и выводит на консоль квадраты чисел от 1 до 9. Для отмены задачи нам надо создать и использовать токен. Вначале создается объект CancellationTokenSource :

Затем из него получаем сам токен:

Чтобы отменить операцию, необходимо вызвать метод Cancel() у объекта CancellationTokenSource:

В данном случае отмена задачи вызывается через секунду, чтобы задача произвела некоторые действия.

В самом методе задачи в цикле мы можем отловить сигнал отмены с помощью проверки свойства token.IsCancellationRequested :

Если был вызван метод cancelTokenSource.Cancel() , то выражение token.IsCancellationRequested возвращает true.

После завершения задачи проверяем ее статус:

Поскольку задача успешно завершена, у задачи должен быть статус RanToCompletion

И в конце у объекта CancellationTokenSource вызываем метод Dispose:

Консольный вывод программы:

Отмена задачи с помощью генерации исключения

Второй способ завершения задачи представляет генерация исключения OperationCanceledException . Для этого применяется метод ThrowIfCancellationRequested() объекта CancellationToken:

Здесь опять же проверяем значение свойства IsCancellationRequested, и если оно равно true, генерируем исключение:

Чтобы обработать исключение, помещаем весь код работы с задачей в конструкцию try..catch и также с помощью вызова cancelTokenSource.Cancel() посылаем сообщение об отмене задачи.

Стоит отметить, что генерируемое исключение будет спрятано в объекте AggregateException, который по сути представляет набор исключений. Если причина исключения состояла в отмене задачи, то мы можем найти в этом наборе исключений исключение типа TaskCanceledException

Класс TaskCanceledException является производным от OperationCanceledException. Исключение типа TaskCanceledException возникает, если для задачи устанавливается статус Canceled .

Консольный вывод программы:

Стоит отметить, что исключение возникает только тогда, когда мы останавливаем текущий поток и ожидаем завершения задачи с помощью методов Wait или WaitAll. Если эти методы не используются для ожидания задачи, то для нее просто устанавливается состояние Canceled. Например, в следующем случае исключение не возникнет:

Консольный вывод программы:

Регистрация обработчика отмены задачи

Выше для проверки сигнала отмены применялось свойство IsCancellationRequested. Но есть и другой способ узнать о том, что был послан сигнал отмены задачи. Метод Register() позволяет зарегистрировать обработчик отмены задачи в виде делегата Action:

Здесь обработчик отмены представлен лямбда-выражением:

Поскольку действие задачи представляет цикл, который выполняется при значении i меньше 10, то установка этой переменной в обработчике отмены приведет к выходу из цикла и соответственно завершению задачи.

Передача токена во внешний метод

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

Похожие статьи