双向命名管道问题双向、管道、问题

2023-09-06 09:36:39 作者:执意要走如何留i

我有2个应用程序,我想提出通过对.NET 3.5的命名管道通信。它是一种请求/响应模式,以作为XML传输的数据,使我的生活更轻松。有一个听众的应用程序,和一个应用程序,职位的请求到管道。我试图用一个双向管做到这一点。我的问题是,调用StreamReader.ReadToEnd()似乎没有返回。我能做些什么来解决这个问题?

监听器code

 公共类监听器
{
    私人无效的ThreadFunc()
    {
       VAR管=新NamedPipeServerStream(GuideSrv.Pipe,PipeDirection.InOut);
       VAR河道=新的StreamReader(管);
       VAR outstream =新的StreamWriter(管);
       而(真)
       {
           pipe.WaitForConnection();
           VAR响应= ProcessPipeRequest(河道);
           outstream.Write(response.ToString());
           pipe.Disconnect();
       }
    }
    私人的XDocument ProcessPipeRequest(StreamReader的流)
    {
        变种msg_in = stream.ReadToEnd(); //<<此调用犯规回报
        VAR xml_in = XDocument.Parse(msg_in);
        //做一些东西在这里
        返回新的XDocument(....);
    }
}
 

申请人code

 公开的XDocument doIt方法()
{
    VAR XML =新的XDocument(....);
    使用(VAR管=新NamedPipeClientStream(。,GuideSrv.Pipe,PipeDirection.InOut))
     {
        使用(VAR outstream =新的StreamWriter(管))
        使用(VAR河道=新的StreamReader(管))
        {
            pipe.Connect();
            outstream.Write(xml.ToString());
            XML = XDocument.Parse(instream.ReadToEnd());
        }
    }
    返回XML;
}
 

解决方案 TPEP防腐钢管介绍及其优良特性

在做 outstream.Write(xml.ToString()) doIt方法()然后尝试从河道阅读。同时您的其他线程正在等待 stream.ReadToEnd()。它会一直等下去,因为它不知道你在写完。至于它知道你很可能叫 outstream.Write()再次写入更多的数据。该 ReadToEnd()调用不会返回,直到你真正从关闭管道doIt方法()

您可以变通的作法是使他们彼此一点点的智能通信。你可以,例如,写 xml.ToString()的长度,管道,然后写入字符串。然后,在你的读者线程您先阅读长度,然后读 msg_in ,您预计要发送的字节数,一旦停止只读确切数量,因为你读它们,而不是等待管道被关闭。

I have 2 apps that I want to make communicate via named pipes on .NET 3.5. Its a request/response paradigm, with the data transmitted as XML to make my life easier. There is a listener app, and an app that posts requests to the pipe. I'm trying to use a bidirectional pipe to do this. The problem i have is that the call to StreamReader.ReadToEnd() doesnt seem to return. What can I do to fix this?

Listener code

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

Requester code

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

解决方案

After you do outstream.Write(xml.ToString()) in doIt() you then try to read from instream. Meanwhile your other thread is waiting in stream.ReadToEnd(). It will wait forever because it doesn't know that you're done writing. As far as it knows you could very well call outstream.Write() again to write some more data. The ReadToEnd() call is not going to return until you actually close the pipe from doIt().

You can work around this by making them communicate with each other a little bit more intelligently. You could, for example, write the length of xml.ToString() to the pipe and then write the string. Then in your reader thread you first read the length and then read msg_in, only reading exact number of bytes you expect to be sent, stopping as soon as you read them all rather than waiting for the pipe to be closed.