Search code examples
c#streamstreamreadernamed-pipesfreeze

C# Named pipe stream readline hangs


Im confused. I have client/server structure of named pipe, and the problem is at some random point, after a while of work it just hangs on the streamReader.ReadLine(); It just stops, and not going further. Im confused, I have no idea at all, what is going on, and actually how to debug that, why and when it happens. Any ideas?

Client side sometimes do:

   private void Connect()
    {
        stream = new NamedPipeClientStream(".", "MP9", PipeDirection.InOut);
        try
        {
            stream.Connect(120);
        }
        catch (Exception e)
        {
            run = false;
            return;
        }

        //Initialising Readers/Writers
        sr = new StreamReader(stream);
        sw = new StreamWriter(stream);
    }

private string SendMessage(string msg)
{
    Debug.WriteLine("Will listen for message " + msg);

    string msgFrom = "";
    if (run)
    {
        string toReturn = "";
        lock (locker)
        {

            sw.WriteLine(msg); //Writing command to the pipes
            stream.WaitForPipeDrain(); //Waiting for another process to read the command
            msgFrom = sr.ReadLine(); //Reading
        }
    }
    return msgFrom;
}

And my server has a thread, that listens for any messages, and responds back if is needed. And after X hrs of running it will just stop at ReadLine, without errors or so. Just stops on the line, and not goes further. However app is still running, it is not hanged, just this listener thread seems hanged...

void Listen()
{
    try
    {
        stream.WaitForConnection();
        sw.AutoFlush = true;
        string messageTo = "";
        while (running) //Main loop of the thread
        {
            messageFrom = "";
            //HERE IT CAN JUST HANG AND NOT GO FURTHER....
            messageFrom = sr.ReadLine(); //Reading

            //populate message to with data, if is needed to respond

            sw.WriteLine(messageTo);
            stream.WaitForPipeDrain();
        }
    }
 }

Solution

  • This seems to happen if you read all the data.

    If you do a "Peek()" and check for a value above 0 before you read you should be able to fix this.

    stream.WaitForConnection();
        sw.AutoFlush = true;
        string messageTo = "";
        while (running) //Main loop of the thread
        {
            messageFrom = "";
            if(sr.Peek() > 0)
            {
               messageFrom = sr.ReadLine(); //Reading
    
              //populate message to with data, if is needed to respond
    
               sw.WriteLine(messageTo);
            }
            stream.WaitForPipeDrain();