我想确保我的逻辑在这里是正确的。我想在timeout
秒运行一个进程,如果它运行的时间更长,它应立即被杀死。
completed
标志应该可靠地指示进程是否按预期完成,例如未被杀死,并且没有崩溃或抛出异常。
另外,如果对process.HasExited
的检查是正确的,我不肯定。如果process.WaitForExit()
返回false并且Kill()
成功,那么process.HasExited
总是是真的吗?这将是我的假设,但我想证实。另外,如果Kill()失败,可以做什么呢?
除了记录?
using (process = new Process())
{
process.EnableRaisingEvents = true;
process.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(OnErrorDataReceived);
process.Exited += new EventHandler(OnExited);
process.StartInfo = startInfo;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
if (!process.WaitForExit(timeout))
{
try
{
process.Kill();
}
catch (Exception e)
{
LogError(e, MethodBase.GetCurrentMethod());
}
finally
{
this.completed = false;
}
}
else
{
if (process.HasExited)
{
this.code = process.ExitCode;
this.completed = true;
}
else
{
this.completed = false;
}
}
}
答案 0 :(得分:4)
是的,HasExited在您的情况下将始终如此。
根据MSDN,
“ HasExited的值为true表示关联的进程已终止,正常或异常。 [...] 进程可以独立终止如果您使用此组件启动了该过程,系统会自动更新HasExited的值,即使关联的进程独立退出。“
但是,如果您的进程在超时之前崩溃并终止,那么您的代码无论如何都会将其设置为已完成。也许您应该检查退出代码,但每个进程可以有different meanings:
if (process.ExitCode != 0)
{
this.completed = false;
}
答案 1 :(得分:2)
我们在.net控制台应用
中使用以下内容private void InitTimer()
{
double lInterval = Convert.ToDouble(AppSettings("MaxExecutionTime"));
lInterval = lInterval * 60 * 1000;
tm = new System.Timers.Timer(lInterval); // global timer object
tm.Elapsed += OnTimedEvent;
tm.Enabled = true;
}
public void ThreadProc(object stateinfo)
{
// set error code here
Environment.Exit(0);
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
Threading.ThreadPool.QueueUserWorkItem(new Threading.WaitCallback(ThreadProc));
}
答案 2 :(得分:1)
在C中,您可以使用闹钟功能设置OS闹钟。当它过期时,SIGALRM将被发送到您的进程,如果没有设置处理程序,它将终止它。
答案 3 :(得分:1)
您可以使用this。它是JobObjects函数的C#包装器。 背后的想法是(我提到的库中嵌入了低级轮廓):
同样使用作业对象可以限制内存使用量。 在我提到的page上,你也可以找到例子。
<强>更新强>
在我写完上述陈述后,我发现了Kill child process when parent process is killed。他们将JobObjects用于另一项任务,但JobObjects的用法应与您的案例相同。