Улучшения API процессов в .NET 11. Окончание
Обзор
Проблемы существующего API
Разбор новых методов
Управление жизненным циклом
Process.StartAndForget
Распространено заблуждение, что при очистке переменной процесса, процесс также завершается. Это не так, поскольку Process.Dispose только освобождает ресурсы, связанные с процессом, но не завершает его.
Чтобы упростить запуск процесса без необходимости беспокоиться о его завершении, добавлен метод Process.StartAndForget, который запускает процесс, возвращает его ID и освобождает все связанные с ним ресурсы.
int processId = Process.StartAndForget("notepad.exe");ProcessStartInfo.KillOnParentExit
Процессы, запущенные родительским процессом, не завершаются автоматически при завершении родительского процесса. Это может привести к появлению «осиротевших» процессов, продолжающих работать в фоновом режиме, что нежелательно во многих сценариях. Для решения этой проблемы добавлено свойство ProcessStartInfo.KillOnParentExit, которое гарантирует завершение дочернего процесса при завершении родительского процесса (включая случаи принудительного завершения и сбоев).
Это достигается за счёт использования специфических для платформы функций, таких как JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE в Windows и PR_SET_PDEATHSIG в Linux и Android. В отличие от других API, поведение немного отличается на разных платформах:
- В Windows используется объект Job, чтобы гарантировать завершение дочернего процесса при завершении родительского процесса. Объекты Job по умолчанию наследуются всеми дочерними процессами, поэтому, если дочерний процесс порождает другой процесс (внука), этот внук также будет завершён при завершении родительского процесса.
- В Linux и Android используется PR_SET_PDEATHSIG для указания сигнала SIGKILL, который ядро отправит дочернему процессу при завершении потока, создавшего процесс. Поскольку как потоки пула потоков, так и пользовательские потоки могут быть завершены в любое время, поддерживается выделенный поток, используемый только для порождения процессов с включенным KillOnParentExit, чтобы гарантировать завершение дочерних процессов при завершении родительского процесса. Таким образом, когда запускается несколько процессов с KillOnParentExit, используется механизм синхронизации, гарантирующий, что выделенный поток запускает только один процесс за раз.
ProcessStartInfo.StartDetached
Свойство ProcessStartInfo.StartDetached позволяет запустить процесс, отсоединённый от родительского процесса, что означает, что он будет продолжать работать, даже если родительский процесс завершится, получит сигнал или будет закрыт терминал. Это достигается с помощью платформенно-специфических функций, таких как флаг DETACHED_PROCESS в Windows и setsid в Unix (PR).
Более того, если StartDetached установлено в true и не указано перенаправление для стандартных обработчиков выводы, они будут перенаправлены на нулевой дескриптор, чтобы избежать ненужного удержания родительских стандартных обработчиков открытыми.
Источник: https://devblogs.microsoft.com/dotnet/process-api-improvements-in-dotnet-11/