我必须处理 Process.Start(url) 吗?

Posted

技术标签:

【中文标题】我必须处理 Process.Start(url) 吗?【英文标题】:Do I have to Dispose Process.Start(url)? 【发布时间】:2010-11-17 11:39:22 【问题描述】:

简单的问题:我想使用默认浏览器打开一个 URL,所以我只做Process.Start(url)。但是,我注意到这会返回一个 IDisposable 对象。

所以现在我想知道我是否必须处理它?或者,就此而言,如果我的应用程序以任何方式负责此过程?预期的功能只是“一劳永逸”,我不想让我的应用程序作为新进程的父进程,并且它不需要与之交互。

我在 SO 上看到了一些类似但不相关的问题,似乎说只需在 URL 上调用 Process.Start 就可以了,但我不想遇到一些难以调试的内存泄漏/资源耗尽问题导致我的我的程序保持对长期死掉的浏览器进程的引用。

【问题讨论】:

【参考方案1】:

难道你不能把它包装在一个using 子句中,以确保如果你需要处理它,GC 会做它需要做的任何事情吗?这仍然允许一种“即发即弃”,但不会使内存/资源处于不良状态。

可能有点矫枉过正,但 CodeProject 上有一篇关于 IDisposable 接口的非常好的文章:http://www.codeproject.com/KB/dotnet/idisposable.aspx

【讨论】:

问题是我没有完全理解这种情况下的对象生命。如果我使用(Process.Start(url));那么它会在那个时候等待吗?或者它会提前处理这个过程吗?目前,这对行为没有影响,所以我没有资源保持开放,但我不确定,也不知道如何衡量。跨度> 由于“using”子句隐式地指示编译器构建一个 try/finally 并实现一个 dispose 以及它们返回一个 IDisposable 对象的事实,我认为你可以安全地这样做。如果不释放它,您可能会占用资源。您可以尝试构建一个打开多个 URL 而不释放它们的循环,并通过将它们包装在 using 子句中来查看您的资源是否膨胀失控并进行另一个测试。需要注意的是,在那之后你会有一堆窗户要关闭。 :)【参考方案2】:

不,你没有。

void Main()

    Process result = Process.Start("http://www.google.com");

    if (result == null)
    
        Console.WriteLine("It returned null");
    

打印

它返回null

来自 MSDN (.NET Framework 4) 上的 Process.Start Method (String):

如果要启动的可执行文件的地址是URL,则进程 没有启动,返回null。

(不过,一般来说,using 语句是处理 IDisposable 对象的正确方法。WCF clients 除外。)

【讨论】:

即使浏览器进程IS启动了,它仍然返回null! @AgentFire 无论您的浏览器是否必须加载,URL 总是会为 null。这就是重点 - 在这种特定情况下(URL),您不必处理。【参考方案3】:

启动进程是一个本机调用,它返回一个本机进程句柄,该句柄存储在返回的 Process 实例中。 Process 中有一些使用句柄的方法,因此您可以执行诸如等待进程退出或空闲等操作。

释放进程释放该句柄。我同意 Jon 的观点,将其包装在 using 子句中。

【讨论】:

【参考方案4】:

@Fooberichu 的回答很到位,但我认为还值得指出的是,通常只有少数东西“需要”明确处理。

对象总是在一些点被有效地处理:

每当 GC 进行收集时,它都会(最终)处理不再引用的对象。因此,如果您不手动处置,对象可能仍会在其超出范围后的几秒钟内被处置。 当您的应用程序退出时,它持有的所有资源都会被释放。 (尽管 C#/.net 可能不会释放对象,但操作系统会收回您的进程抓取的几乎所有内容。如果资源的生命周期超出您的应用程序,那么操作系统通常负责清理它)李>

因此,手动处置(或使用“使用”)的目的不是确保资源释放,而是尽早释放它们 .

如今,您不太可能用完大多数类型的资源(例如内存、文件句柄或系统画笔)。但是,如果您在不需要的时候保留资源,您的程序可能会效率较低,您可能会使用比必要更多的内存,或者可能会通过暂时阻止其他应用程序执行有用的事情而导致延迟,等等。总而言之,Disposing 是关于良好的礼仪、整洁和减少不必要的低效率。

在某些情况下必须释放资源(例如,如果您不关闭文件,则无法从程序的其他位置或其他位置打开/重命名/移动/删除它程序;如果你一直在你的显卡上分配纹理而不释放它们,你会耗尽 VRAM 并且计算机的显示会失败),但一般来说,你会很少遇到这些情况,如果你遵循最佳实践(显式处理不再需要的对象),您通常不需要知道这些情况何时发生,因为您已经正确地处理了它们。

【讨论】:

在许多情况下,IDisposable 类没有终结器。如果它们在没有被显式处理的情况下被 GC 处理,则与它们关联的任何非托管资源都将被泄露。在大多数情况下,框架类可以很好地保护我们,但最佳实践是始终处置 IDisposable 对象。这和 WCF 客户端恰好是两个奇怪的边缘情况。 Any time the GC does a collection, it will (eventually) dispose of objects that are no longer referenced. So if you don't manually dispose, the object may still be disposed within a few seconds of it going out of scope. 这无法保证。终结器不保证调用Dispose。它最终会垃圾收集是的(嗯,技术上“可能”)-但不一定是Dispose

以上是关于我必须处理 Process.Start(url) 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Process.Start() 打开 URL 有时会抛出 Win32Exception?

Process.Start 无法正确运行批处理文件

谁能帮我处理由 func Process.Start(); 调用的进程?

csharp Process.Start for .NET Core上的URL

当我调用 process.start() 时,Python 多处理进程只会停止我的代码运行

Process.Start() 啥都不做