【问题标题】:Process.WaitForExit(Int32)Process.WaitForExit(Int32)
【发布时间】:2014-02-05 12:40:07
【问题描述】:

现在我正在开发一个 Console Runner 应用程序,该应用程序具有以下代码来输出日志并等待该过程完成:

using (Process p = Process.Start(ps))
{
    p.OutputDataReceived += OutputReceived;
    p.ErrorDataReceived += ErrorReceived;
    p.BeginOutputReadLine();
    p.BeginErrorReadLine();
    p.WaitForExit(30000);
    return p.ExitCode;
}

我对这段代码有两个问题。

  1. 我注意到,如果处理时间超过 30 秒,调用 p.ExitCode 就会爆炸。
  2. 如果我的进程只需要 1 秒会发生什么,它会等待 30 秒还是 CLR 会通知该进程?

【问题讨论】:

  • 他们在文档中隐藏了这些秘密:"如果您在进程退出之前尝试获取 ExitCode,则该尝试会引发异常。首先检查 HasExited 属性以验证关联的进程是否已终止。" 和 "WaitForExit ... 并阻塞当前执行线程,直到时间过去或进程退出"
  • 我也找到了它,但我不确定我是否正确阅读了它。因此,如果进程在 WaitForExit 内的时间戳之前退出似乎没有问题,但反过来会导致一个很好的异常。谢谢

标签: c# process


【解决方案1】:

来自ExitCodedocumentation

如果您在进程退出之前尝试获取 ExitCode,则该尝试会引发异常。首先检查 HasExited 属性以验证关联的进程是否已终止。

无法保证当您对WaitForExit 的调用返回时,该进程将退出。来自WaitForExitdocumentation

WaitForExit(Int32) 重载用于使当前线程等待,直到相关进程终止。此重载指示 Process 组件等待有限的时间以使进程退出。如果由于终止请求被拒绝,关联进程在间隔结束时没有退出,则将 false 返回到调用过程。您可以为毫秒指定一个负数(无限),并且 Process.WaitForExit(Int32) 的行为与 WaitForExit() 重载相同。如果将 0(零)传递给该方法,则仅当进程已经退出时它才返回 true;否则,它立即返回 false。

请注意,这回答了您的第二个问题。如果进程在超时之前退出,WaitForExit 返回。

由于您指定了有限超时,因此您允许函数在进程完成之前返回。所以,你可以这样写你的代码:

if (p.WaitForExit(30000))
    return p.ExitCode;
else
    return NotFinishedExitCode;

或者更简洁的条件表达式:

return p.WaitForExit(30000) ? p.ExitCode : NotFinishedExitCode;

【讨论】:

  • 谢谢大卫的解释,我会试一试
猜你喜欢
  • 2016-08-01
  • 2010-10-02
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多