0

I've written some code that uses named pipes to send a string from one application to another. It works fine once, but when the client tries to send the to the server application for a second time it freezes when it tries to connect to the client.

The server code is this:

static void StartServer()
{
   Task.Factory.StartNew(() =>
   {
      var server = new NamedPipeServerStream("MyPipe");
      server.WaitForConnection();
      StreamReader reader = new StreamReader(server);

      while (true)
      {
         var line = reader.ReadLine();

         if (line != null)
         {
            System.Windows.Forms.MessageBox.Show("Data: : " + line);
         }
      }
   });
}

The client code is:

private void Test()
{
    using (var client = new NamedPipeClientStream("MyPipe"))
    {
        client.Connect();
        StreamWriter writer = new StreamWriter(client);

        writer.WriteLine("INCOMING:1234567");
        writer.Flush();
        client.Dispose();
    }
}

Tracking the code through, I can see that loop in the server code is continuously checking for any lines being read in but not finding any. The client is hanging on the client.Connect() call when the Test() method is called for a second time. No exceptions are raised.

Can anyone see where I'm going wrong?

GrandMasterFlush
  • 6,269
  • 19
  • 81
  • 104

2 Answers2

1

Your server stays connected to the first pipe instance used to send the first string.

However, your client is disposing its pipe instance after each test, so the second test creates and tries to connect on a new pipe instance, but the server is no longer listening, so the Connect call blocks waiting for a server.

You need to either:

  1. make your server multithreaded, so that it continues listening while servicing instances already connected; or
  2. Refactor your client so that it connects once, then reuses that connected instance.
Chris Dickson
  • 11,964
  • 1
  • 39
  • 60
1

Following on from what @Chris Dickson answered, I solved my problem with the following code:

Task.Factory.StartNew(() =>
{
    var server = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);

    StreamReader reader = new StreamReader(server);    
    Boolean connectedOrWaiting = false;

    while (true)
    {

        if (!connectedOrWaiting)
        {
            server.BeginWaitForConnection((a) => { server.EndWaitForConnection(a); }, null);    
            connectedOrWaiting = true;
        }

        if (server.IsConnected)
        {
            var line = reader.ReadLine();

            if (line != null)
                 System.Windows.Forms.MessageBox.Show("Data: : " + line);

            server.Disconnect();    
            connectedOrWaiting = false;
        }                    
    }
});
GrandMasterFlush
  • 6,269
  • 19
  • 81
  • 104