NamedPipeServerStream.BeginWaitForConnection 失败并显示 System.IO.Exception:管道正在关闭

NamedPipeServerStream.BeginWaitForConnection fails with System.IO.Exception: The pipe is being closed

我用 C# 编写了一个简单的异步 NamedPipeStreamServer 进程,其核心是:

public void Listen()
{
    bool shuttingDown = false;
    while (!shuttingDown)
    {
        NamedPipeServerStream serverStream =
            new NamedPipeServerStream(
                "bobasdfpipe",
                PipeDirection.InOut,
                254,
                PipeTransmissionMode.Message,
                PipeOptions.Asynchronous);

        IAsyncResult connectionResult = 
                serverStream.BeginWaitForConnection(
                    this.HandleConnection,
                    serverStream);

        int waitResult =
            WaitHandle.WaitAny(
                new[]
                    {
                        this.ShutdownEvent,
                        connectionResult.AsyncWaitHandle
                    });
        switch (waitResult)
        {
            case 0:
                // this.ShutdownEvent
                shuttingDown = true;
                break;

            case 1:
                // connectionResult.AsyncWaitHandle
                serverStream.EndWaitForConnection(connectionResult);
                break;
        }
    }
}

我也为它写了一个简单的客户端。客户端(不是异步的)只是打开管道然后退出:

static void Main(string[] args)
{
    using (
        NamedPipeClientStream clientStream =
            new NamedPipeClientStream(
                ".",
                "bobasdfpipe",
                PipeDirection.InOut))
    {
        clientStream.Connect();
    }
}

如果我启动服务器,然后启动一个或多个客户端,似乎一切正常。

如果我在没有启动服务器的情况下启动客户端,客户端会挂起 Connect() 调用,直到我启动服务器,但是当我启动服务器时,服务器崩溃并显示 System.IO.Exception 在 BeginWaitForConnection() 调用中,说 "The pipe is being closed."

我发现其他人在 BeginWaitForConnection() 上有 "The pipe is being closed" 错误,但它们都是由于在同一个 NamedPipeServerStream 实例上尝试第二次 BeginWaitForConnection() 调用引起的。这不是这里发生的事情 - 我为每个 BeginWaitForConnection() 调用创建了一个不同的 NamedPipeServerStream 实例,即使我没有这样做,它还是在第一个 BeginWaitForConnection() 调用上失败了。

我是不是做错了什么?或者这只是正常现象 - 等待服务器启动的命名管道客户端将导致 "The pipe is being closed" 服务器的第一个 BeginWaitForConnection() 调用?

我注意到,如果我再试一次 - 即吸收异常并执行另一个 BeginWaitForConnection() - 然后我会为每个一直在等待服务器启动但在处理之后的客户端得到一个这样的异常所有这些,此后服务器似乎工作正常。

编辑: 这是 HandleConnection 方法,但我认为它甚至没有命中此代码:

private void HandleConnection(IAsyncResult iar)
{
    NamedPipeServerStream serverStream =
        (NamedPipeServerStream)iar.AsyncState;

    Log.Info("So, that happened.");
    Thread.Sleep(1000);
    Log.Info("Giving up.");
}

看起来客户端在服务器完全处理之前关闭了连接。发生这种情况是因为 clientStream.Dispose()clientStream.Connect() 之后立即被调用,并且即将建立的连接被终止。 提示:尝试在 clientStream.Connect() 之后添加 Thread.Sleep(100)

Am I doing something wrong? Or is this just normal - a named pipe client that is waiting for the server to come up will cause "The pipe is being closed" on the server's first BeginWaitForConnection() call?

无论客户端做什么,服务器代码都应该能够通过捕获 IOException 丢弃服务器的管道句柄来优雅地处理这一系列事件。

   NamedPipeServerStream serverStream =
        new NamedPipeServerStream(
            "bobasdfpipe",
            PipeDirection.InOut,
            254,
            PipeTransmissionMode.Message,
            PipeOptions.Asynchronous);

    try 
    {  
        IAsyncResult connectionResult = serverStream.BeginWaitForConnection(
                this.HandleConnection,
                serverStream);


       int waitResult =
           WaitHandle.WaitAny(
               new[]
                {
                    this.ShutdownEvent,
                    connectionResult.AsyncWaitHandle
                });
        switch (waitResult)
        {
          case 0:
            // this.ShutdownEvent
            shuttingDown = true;
            break;

          case 1:
            // connectionResult.AsyncWaitHandle
               serverStream.EndWaitForConnection(connectionResult);
               break;
         }    

    }
    catch(IOException)
    {
        // Connection terminated by client, close server pipe's handle
        serverStream.Close();
        continue;
    }