2

为了简单起见,我正在编写一个名为“APPLICATION A”的程序,它打开一个到本地主机上端口 8881 的套接字连接;后来它使用代码生成一个exe应用程序调用“APPLICATION B”:

        try
        {
            XmSam.Log("Spawning (" + process + ")");

            ProcessEx proc = new ProcessEx();

            proc.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + process + ".exe";
            proc.StartInfo.Arguments = parameters;
            proc.StartInfo.UseShellExecute = false;
            proc.Start();

            Program.Processes.Add(proc);

            XmSam.Log("Spawned " + proc.ProcessName);
        }
        catch (Exception ex)
        {
            XmSam.Log(ex);
        }

当我关闭应用程序 A(通过停止应用程序或在窗口任务管理器中终止其进程)时,应用程序 B 仍然运行,这很好。但是,当我再次启动 APPLICATION A 时,我遇到了异常:

2012-10-18 16:21:23 - Only one usage of each socket address (protocol/network address/port) is normally permitted
2012-10-18 16:21:23 -    at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)

当应用程序 A 试图打开到端口 8881 的套接字时发生此错误。如果我终止应用程序 B,此错误将消失。我认为这不是因为应用程序 B 代码,因为它没有任何内容,如下面的代码所示:

    [STAThread]
    static void Main()
    {
        while (true)
        {
        }
    }

我试图在 Process 类下查看 MSDN,但我没有看到任何关于此的内容。我假设当您生成一个进程时,该进程独立于调用应用程序,但显然情况并非如此。你知道有什么设置可以让我生成一个进程而不让它持有调用应用程序吗?

我知道另一种方法是让应用程序 A 中的代码杀死应用程序 B,但这不是理想的解决方案,尤其是在应用程序 A 意外崩溃的情况下。

谢谢你。

4

2 回答 2

2

经过更多的挖掘,我找到了答案。我发现这篇很棒的文章

其中,对这个问题的主要解释如下:

System.Diagnostics.Process.Start 使子进程从父进程继承句柄。这意味着,无论您生成什么进程(例如 Internet Explorer),该进程都会获得您的进程拥有的所有句柄!因此,即使您释放进程中的句柄,如果您生成的进程仍在运行,您的句柄也不会真正被释放,因为子进程应该正在使用它们。

因此,考虑到这一点,我所要做的就是将我的 UseShellExecute 标志更新为 true。

proc.StartInfo.UseShellExecute = true;
于 2012-10-19T14:40:46.737 回答
0

您应该确保应用程序 A 在关闭套接字时关闭它。我认为 Application.ApplicationExit Event 是一个很好的地方,或者当你完成套接字时。

于 2012-10-19T13:44:43.723 回答