【问题标题】:C# Process.Start() failed to dispose thread resourcesC# Process.Start() 未能释放线程资源
【发布时间】:2011-12-20 14:54:59
【问题描述】:

程序代码如下:

using System.Diagnostics;

class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
        }
    }
}

问题是当这个程序已经关闭并且记事本仍在运行时,记事本会锁定它。而且我不想关闭记事本。
我尝试使用 Unlocker 来检测问题。
结果截图如下:

Result Image Link

所以我想要的是启动一个 exe 文件并立即处理所有线程资源。或者我无法卸载我的程序,直到它打开的所有程序都关闭。这可能会导致不愉快的用户体验。要求系统重新启动也令人不快。 Unlocker 可以很好地做到这一点。如果我用Unlocker解锁父文件夹,它不会关闭记事本,然后我可以正常删除这个程序文件。

【问题讨论】:

  • 你为什么要对包裹在 using 语句中的对象调用 Dispose
  • 锁定什么?你想做什么?
  • 首先,using 语句本身会在退出时调用 dispose。其次,您可能想使用WaitForExit
  • 我相信这是导致锁定的 VS 调试器(我想知道是什么)。记事本不锁定任何东西,甚至不保持文件处于打开状态。

标签: c# .net process


【解决方案1】:

问题是你从来没有关闭正在运行的进程,所以它继续运行,导致Unlocker提示它被锁定了。

我知道你认为你这样做了,因为你调用了p.Close(),但诀窍是Process.Close() method 确实不会导致进程关闭。它不会向记事本窗口发送WM_CLOSEWM_QUIT 消息。它所做的只是释放与进程相关的资源。

相反,您需要使用Process.CloseMainWindow() method。这将向窗口发送WM_CLOSE 消息,使其正常关闭。

所以更新您的代码,使其看起来像这样(正如其他人所提到的,如果您已经将对象创建包装在 using 语句中,则无需显式调用 Dispose):

using System.Diagnostics;

class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
            p.CloseMainWindow();
            p.Close();
        }
    }
}

请注意,您可以使用Process.Kill() method,但这就像通过将电源线从墙上撕下来关闭计算机一样。它不是要求应用程序很好地关闭,而是强制它终止,就像在任务管理器中单击“结束任务”一样。因此,仅当进程被锁定或不响应礼貌的关闭请求时才应使用它。


另外,正如 Rolice 在评论中提到的,上面的代码不会很有用。您只是启动记事本,然后立即关闭它。

相反,您可能希望启动进程,允许用户与之交互,然后在他们完成后清理。

在这种情况下,您需要使用Process.WaitForExit() 方法。此方法将阻塞调用线程,无限期地等待进程退出。当用户最终关闭记事本时,控制权将返回到应用程序的线程,您可以调用p.Close()

例如:

using System.Diagnostics;

class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
            p.WaitForExit();
            p.Close();
        }
    }
}

【讨论】:

  • 谢谢。问题来自自我更新程序。我想删除我之前可能会打开一些其他程序的程序文件。
【解决方案2】:

这里有两种可能的解决方案

  1. 在您的应用程序中,等待进程退出,然后再退出您的应用程序。有severalways可以做到这一点。
  2. 当您的应用程序退出时终止进程。 nicelyby force 都不是很好,如果用户正在编辑某些内容,可能会导致数据丢失。

在上面的情况 #1 中,您可以向用户弹出一个对话框或其他内容,通知您正在等待记事本退出(可能有一个按钮来杀死它)

【讨论】:

    【解决方案3】:

    尝试直接启动该过程而不参考它:

    Process.Start("notepad.exe");
    

    【讨论】:

    • 这个答案是错误和有害的。没有确定的破坏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 2011-02-15
    • 1970-01-01
    • 2011-03-04
    相关资源
    最近更新 更多