Как определить, связан ли процесс с объектом System.Diagnostics.Process? - PullRequest
4 голосов
/ 21 мая 2010

Учитывая конкретный System.Diagnostics.Process , которому присвоены значения для его свойств .FileName и .Arguments, каков наилучший способ определить, является ли оно:

  1. когда-либо была выдана команда .Start() или
  2. в настоящее время вообще связан с процессом?

Если .Start() никогда не выдавалось, то вызов .CloseMainWindow() вызывает исключение InvalidOperationException, которого я бы хотел избежать.

Ответы [ 3 ]

3 голосов
/ 28 августа 2013

Если вы закрываете процесс, вызывая .CloseMainWindow(), , заверните вызов в блок try / catch - это то, что нужно сделать.

Сделайте это:

try
{
    process.CloseMainWindow()
}
catch (InvalidOperationException)
{
    // purposely do nothing here - the process exited before we told it to.
}

Это потому, что проверка свойств процесса перед его остановкой создает условие гонки : и проверка свойства, и вызов .CloseMainWindow() мчатся, чтобы выяснить, какое из них может быть завершено первый.

Рассмотрим эту серию событий:

  1. Процесс запущен
  2. Ваш код звонит process.HasExited и получает false
  3. Процесс завершается сам по себе, поскольку он завершен
  4. Поскольку шаг 2 вернул false, ваш код вызывает process.CloseMainWindow() и получает InvalidOperationException: Process has exited, so the requested information is not available.

Никакое ускорение вашего кода, ни использование блокировок, ни какая-либо другая стратегия не могут гарантировать, что процесс не завершится после вашего оператора if. Всегда есть условия гонки. Поэтому вместо этого используйте try/catch.

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

class ProcessWrapper
{
    public HasStarted;
    public ProcessWrapper(Process p, ProcessStartInfo psi)
    {
        // do argument and filename validation etc. here
        lock(HasStarted)
        {
            p.Start(psi);
            HasStarted = true;
        }
    }
}
2 голосов
/ 21 мая 2010

Вы пробовали проверить Process.Id и одно из свойств выхода?

Ref .

В ответ на комментарии автора: возможно, вам придётся завершить попытку / поймать, а выбрасываемое исключение означает, что не запущено? Это не красиво!

0 голосов
/ 21 мая 2010

Вы можете попробовать и проверить

process.StartTime & process.HasExited
process.Handle

или, возможно, использовать

process.WaitForExit
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...