C# 命名管道流 readline 挂起

C# Named pipe stream readline hangs

我很困惑。我有命名管道的 client/server 结构,问题出在某个随机点,经过一段时间的工作后它只是挂在 streamReader.ReadLine(); 它只是停下来,并没有继续前进。我很困惑,我完全不知道发生了什么,实际上如何调试它,为什么以及何时发生。有什么想法吗?

客户端有时会做:

   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;
}

我的服务器有一个线程,用于侦听任何消息,并在需要时进行响应。在 运行 的 X 小时后,它会在 ReadLine 处停止,不会出现任何错误。只是停在了线上,并没有走得更远。但是应用程序仍然 运行,它没有挂起,只是这个侦听器线程似乎挂起...

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();
        }
    }
 }

如果您阅读所有数据,这似乎会发生。

如果您在阅读之前执行 "Peek()" 并检查是否有大于 0 的值,您应该能够解决此问题。

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();