在没有WaitForExit()的using语句中,进程会发生什么?

6
在下面的例子中,如果代码离开using语句时进程仍在运行,会发生什么?
using (var p = new Process())
{
    p.StartInfo.FileName = "c:\\temp\\SomeConsoleApp.exe";
    p.Start();
}
4个回答

11

应该将在您的系统上运行的操作系统进程与Process对象分离开来, 代表它在程序中的“处理”:

  • 进程会继续运行,直到完成或使用特定于操作系统的方法杀死它
  • Process对象被处理掉,因此您的程序无法再与操作系统进程交互。

Process对象上调用Dispose()方法不会杀死操作系统进程。


使用特定于操作系统的方法终止它。 怎样才能知道,例如 System.Diagnostics.Process.Kill() 是否特定于某个操作系统? 我在文档中没有看到任何相关信息。或者这个事实表明:“它不是特定于操作系统的”? - user1234567
@user1234567 我的意思是像UNIX上的kill <pid>或Windows上的taskkill /F /PID <pid>这样的操作,而不是C#方法。 - Sergey Kalinichenko

1
你可能知道,using语句将调用Dispose方法,因此进程实例将被处理。
要与进程交互、获取进程相关信息,需要Handle to the Process。.Net框架内部持有进程的句柄,并为您处理所有繁琐的操作。Dispose将关闭进程的Handle,因此您将无法再以良好的方式使用Process对象。
最重要的是:您启动的进程不会发生任何事情,它会像什么都没有发生一样运行。真的什么都没有发生,你只是丢失了打开门的钥匙,这并不意味着房间被摧毁了。

0

进程将继续运行。您可以将进程p移动到类成员中,并在OnStop中停止进程,以确保如果exe出现故障,您可以再次停止服务。

protected override void OnStop()
{
    p.Kill();
}

0

进程将一直运行,直到您关闭它。它不会因为进程对象作用域结束而死亡。


@SriramSakthivel OP使用了using,因此他期望如果对象超出范围,进程将终止。 - Pranit Kothari
@SriramSakthivel 一旦他走出 using 块,p 就会死亡。因此他期望生成的进程也应该死亡。 - Pranit Kothari
“p会死”这个说法不太清楚。你所谓的“死”是指什么?实际上,所有发生的事情就是在进程实例上调用了“Dispose”方法,然后就结束了。你的答案确实是正确的,但是其中的作用域部分对我来说有点困惑。 - Sriram Sakthivel
@SriramSakthivel 我的意思是说,在 using 块之外,p 不会被使用。这意味着它将被垃圾回收。我错了吗? - Pranit Kothari
假设 p 在使用块之外被定义并作为类中的字段存储。那么,如果使用 using(this.p){...},则 p 不会超出范围或被垃圾回收。它只会被处理。这里的主要问题是进程被处理时会发生什么,而不是进程超出范围时会发生什么。我认为这很有道理。 - Sriram Sakthivel
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接