Каждый раз, когда вы вызываете Start()
на экземпляр Process
, создается новый процесс и система выделяет ему ресурсы. Такими ресурсами являются дескриптор процесса и другие атрибуты, такие как код выхода и время выхода. Если вы пишете что-то вроде:
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.Start();
p.WaitForExit();
var exitCode = p.ExitCode;
Console.WriteLine("Handle: {0}, PID: {1}, Exit code: {2}", p.Handle.ToInt32(), p.Id, exitCode);
p.StartInfo.FileName = "cmd.exe";
p.Start();
p.WaitForExit();
exitCode = p.ExitCode;
Console.WriteLine("Handle: {0}, PID: {1}, Exit code: {2}", p.Handle.ToInt32(), p.Id, exitCode);
и делают оба процесса возвращают разные значения (набрав в командной строке Windows, например выхода 1 и выход 2 соответственно), вы получите результат, похожий на этот:
Handle: 1308, PID: 9060, Exit code: 1
Handle: 1324, PID: 8428, Exit code: 2
Технологические свойства, такие как ExitCode
и Handle
правильно возвращать значения для последнего завершенного процесса. Но они потеряны для процесса, запущенного ранее, и вы также имеете утечку в ресурсе, поскольку системные ресурсы, выделенные для предыдущего процесса не были захоронены (следующая цитата из MSDN):
Если ручка открыта к процессу, операционная система освобождает память процесса , когда процесс вышел, но сохраняет административную информацию о процессе, такую как дескриптор, код выхода и выход . Чтобы получить эту информацию, вы можете использовать свойства ExitCode и ExitTime . Эти свойства автоматически заполняются для процессов , которые были запущены этим компонентом. Административная информация: , если все компоненты Процесса, связанные с системным процессом , уничтожены и не содержат больше обработок для выхода .
Process
тип реализует IDisposable
интерфейс и эти компоненты разрушаются при вызове Close()
(или Dispose()
) на экземпляре Process
(следующая цитата из MSDN):
Близкий метод заставляет процесс прекратить ждать выхода, если он был ожидания, закрывает дескриптор процесса и очищает свойства , специфичные для конкретного процесса. (...) Метод Dispose вызывает Close. Размещение объекта объекта в используемом блоке предоставляет ресурсы без необходимости звонить Закрыть.
Правильный способ использования Process
для запуска двух процессов будет включать в себя вызов Dispose()
:
using (var p = new Process())
{
p.StartInfo.FileName = "cmd.exe";
p.Start();
p.WaitForExit();
var exitCode = p.ExitCode;
Console.WriteLine("Handle: {0}, PID: {1}, Exit code: {2}", p.Handle.ToInt32(), p.Id, exitCode);
}
using (var p = new Process())
{
p.StartInfo.FileName = "cmd.exe";
p.Start();
p.WaitForExit();
var exitCode = p.ExitCode;
Console.WriteLine("Handle: {0}, PID: {1}, Exit code: {2}", p.Handle.ToInt32(), p.Id, exitCode);
}
Я считаю, что вы можете начать новый процесс вместо нового набора начальной информации о том же процессе. –
Соглашаясь с @ZackCampbell, это похоже на дефект дизайна, позволяющий дважды запускать 'Start'. –