C# 如何在不终止进程的情况下处置System.Diagnostics.Process对象?

C# 如何在不终止进程的情况下处置System.Diagnostics.Process对象?,c#,.net,C#,.net,我有一个应用程序,它创建流程对象以启动外部应用程序。一旦它验证了应用程序是否正确启动,它就不再关心它,因此我不再需要Process对象,但我无法对其调用Dispose(),因为我不想关闭该进程。解决方法是什么?您可以安全地处置流程实例,流程将在之后运行 class Program { static void Main(string[] args) { Process p = new Process { StartInfo =

我有一个应用程序,它创建流程对象以启动外部应用程序。一旦它验证了应用程序是否正确启动,它就不再关心它,因此我不再需要Process对象,但我无法对其调用Dispose(),因为我不想关闭该进程。解决方法是什么?

您可以安全地处置流程实例,流程将在之后运行

class Program
{
    static void Main(string[] args)
    {
        Process p = new Process
        {
            StartInfo = {FileName = "notepad.exe"}
        };
        p.Start();

        p.Dispose();
        // Notepad still runs...
        GC.Collect(); // Just for the diagnostics....
        // Notepad still runs...
        Console.ReadKey();
    }
}

实际上,进程(Notepad.exe)甚至会在.NET应用程序终止后运行。顺便说一句,这就是我建议不要担心进程实例并在进程实际终止之前处理它们的原因之一:您将失去停止OS进程或查询其状态的控制句柄。除非你有无数的进程实例,否则我不必担心它们。

我认为
Process.Close()
Process.Dispose()
不要杀死进程。它们只是释放一些与处理流程相关的资源

从:


我看不到任何应该终止进程的东西。

为什么需要处理它?@DStanley,因为它实现了IDisposable。您总是需要处理这些对象,否则会泄漏句柄或其他非托管资源。@健忘症您确定这会终止进程吗?你试过了吗?@antiduh遗憾的是,重复的回答只说“你真的应该处理它”,但没有说它是否会扼杀这个过程:-)投票重新开始。正如@xanatos所指出的,dupe目标及其答案并没有解决处理Process对象是否会杀死进程的问题。最终结论是正确的,但是源代码没有证明这一点:我们看不到base中发生了什么。Dispose(disposing)@g、 pickardou但我有:-)基类是一个
组件
,它的
Dispose
执行一些
组件
清理。最后,在
this.m_processHandle.Close()之后进程
(类)无法再控制进程,因为这是进程的Windows
句柄
。我相信你看到了,我刚才提到提供的示例并不能证明它。哇,我是个白痴,我只是假设没有测试。谢谢你的证明。告诉别人不要费心处理东西是一个糟糕的建议——因为它是一次性的。原因是
进程
对象在有效时保留机器范围的资源(进程句柄)<代码>进程实现了一个终结器,因此在构造终结器队列后,它会立即注册到终结器队列中;除非调用
Dispose()
,否则它将保留在该队列中。需要一次GC运行来发现对象已被释放,一次终结器运行来运行终结器并释放这些句柄,另一次GC运行来回收对象的内存。始终处置处置处置有关处置
流程
对象的确切原因的详细信息,请参阅以下回答:antiduh:你完全正确,我的意思是“建议不要担心流程实例,并在流程实际终止之前处置它们”。我已经编辑了我的答案
protected override void Dispose(bool disposing) {
    if( !disposed) {
        if (disposing) {
            //Dispose managed and unmanaged resources
            Close();
        }
        this.disposed = true;
        base.Dispose(disposing);                
    }            
}
public void Close() {
    if (Associated) {
        if (haveProcessHandle) {
            StopWatchingForExit();
            Debug.WriteLineIf(processTracing.TraceVerbose, "Process - CloseHandle(process) in Close()");
            m_processHandle.Close();
            m_processHandle = null;
            haveProcessHandle = false;
        }
        haveProcessId = false;
        isRemoteMachine = false;
        machineName = ".";
        raisedOnExited = false;

        //Don't call close on the Readers and writers
        //since they might be referenced by somebody else while the 
        //process is still alive but this method called.
        standardOutput = null;
        standardInput = null;
        standardError = null;

        output = null;
        error = null;

        Refresh();
    }
}