双向命名管道问题

Jef*_*ock 2 .net bidirectional named-pipes .net-3.5

我有两个应用程序,我想通过.NET 3.5上的命名管道进行通信.它是一个请求/响应范例,数据以XML格式传输,使我的生活更轻松.有一个监听器应用程序,以及一个将请求发布到管道的应用程序.我正在尝试使用双向管道来做到这一点.我遇到的问题是对StreamReader.ReadToEnd()的调用似乎没有返回.我该怎么做才能解决这个问题?

听众代码

public Class Listener
{
    private void ThreadFunc()
    {
       var pipe = new NamedPipeServerStream("GuideSrv.Pipe",PipeDirection.InOut);
       var instream = new StreamReader(pipe);
       var outstream = new StreamWriter(pipe);
       while (true)
       {
           pipe.WaitForConnection();
           var response = ProcessPipeRequest(instream);
           outstream.Write(response.ToString());
           pipe.Disconnect();
       }
    }
    private XDocument ProcessPipeRequest(StreamReader stream)
    {
        var msg_in = stream.ReadToEnd();  // << This call doesnt return
        var xml_in = XDocument.Parse(msg_in);
        // do some stuff here 
        return new XDocument(....);
    }  
}
Run Code Online (Sandbox Code Playgroud)

请求者代码

public XDocument doIt()
{
    var xml = new XDocument(....);
    using (var pipe = new NamedPipeClientStream(".", "GuideSrv.Pipe", PipeDirection.InOut))
     {
        using (var outstream = new StreamWriter(pipe))
        using (var instream = new StreamReader(pipe))
        {
            pipe.Connect();
            outstream.Write(xml.ToString());
            xml = XDocument.Parse(instream.ReadToEnd());
        }
    }
    return xml;
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ica 6

在你outstream.Write(xml.ToString())进入doIt()之后然后尝试阅读instream.与此同时你的另一个线程正在等待stream.ReadToEnd().它会永远等待,因为它不知道你写完了.据他所知,你可以outstream.Write()再次打电话再写一些数据.在ReadToEnd()您实际关闭管道之前,调用不会返回doIt().

您可以通过使它们更智能地相互通信来解决这个问题.例如,您可以将长度写入xml.ToString()管道,然后写入字符串.然后在你的读者线程中,你首先读取长度,然后读取msg_in,只读取你希望发送的确切字节数,一读完就停止,而不是等待管道关闭.