如何确定进程是否与System.Diagnostics.Process对象相关联?

时间:2010-05-20 23:51:53

标签: c# process

鉴于已为其属性​​.FileName.Arguments分配了值的特定 System.Diagnostics.Process ,确定它的最佳方法是什么:

  1. 曾经发出.Start()命令或
  2. 目前与某个流程相关联?
  3. 如果从未发出.Start(),则调用.CloseMainWindow()会导致InvalidOperationException,我想避免这种情况。

3 个答案:

答案 0 :(得分:3)

如果您通过调用.CloseMainWindow()关闭流程,将调用包装在try / catch块中是正确的做法。

这样做:

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

这是因为在关闭流程之前检查流程属性会创建 race condition :属性检查和对.CloseMainWindow()的调用都在竞争以查看哪些可以完成第一

考虑这一系列事件:

  1. 流程正在运行
  2. 您的代码调用process.HasExited并收到false
  3. 该过程自行退出,因为它已经完成
  4. 由于第2步返回false,您的代码会调用process.CloseMainWindow(),并获得InvalidOperationException: Process has exited, so the requested information is not available.
  5. 加快代码加速,使用锁定或任何其他策略都无法保证在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;
            }
        }
    }
    

答案 1 :(得分:2)

您是否尝试过检查Process.Id和其中一个退出属性?

Ref

回应海报的评论:也许你必须包装一个try / catch并抛出一个异常表明没有启动?它不漂亮!

答案 2 :(得分:-3)

您可以尝试检查

process.StartTime & process.HasExited
process.Handle

或者可能使用

process.WaitForExit