Search code examples
c#windows-servicesnamed-pipes

Named pipe is closing on its own after reading one message


I am trying to run a named pipe server on a windows service for an ASP.net web API to communicate with. I have got the ASP.net to be able to send a message but immediately after reading from the pipe it closes, not just the client server connection, the named pipe service simply disposes itself. When I try to call write after reading to send returned data I get error "Cannot access a closed pipe." same error occurs when trying to call WaitForConnection(). I am not sure what is causing this and why it occurs. The Windows Service stays running so that isn't an issue.

Method to start named pipe server

private void StartNamedPipeServer()
{
// set up security
        PipeSecurity pipeSecurity = new PipeSecurity();

// create and handle named pipe
        pipeServer = new NamedPipeServerStream("test", PipeDirection.In, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Message, PipeOptions.None, 1024, 1024, pipeSecurity);
        HandleNamedPipeConnections();
}

Method to handle the execution of named pipe

private void HandleNamedPipeConnections()
{
        while (true)
        {
            pipeServer.WaitForConnection();
            try
            {
                using (StreamReader reader = new StreamReader(pipeServer))
                {
                    string request = reader.ReadToEnd().Trim();
                    // Handle request here
                }
            }
            finally
            {
                if (pipeServer.IsConnected)
                {
                    pipeServer.Disconnect();
                }
            }
        }
}

Method for setting up client

pipeClient = new NamedPipeClientStream(".", "test", PipeDirection.InOut);
pipeClient.Connect();

using (StreamWriter writer = new(pipeClient))
{
    writer.WriteLine(request);
}

Solution

  • I think the new StreamReader(pipeServer) is to blame, when StreamReader closes, at the end of the using, it also closes the underlying stream (in your case, pipeServer)

    There should be a leaveOpen parameter when creating the StreamReader, which stops it from closing the stream when the reader closes. try:

    using (StreamReader reader = new StreamReader(pipeServer, leaveOpen=true))