双向命名管道问题

发布于 2024-08-02 16:01:12 字数 1422 浏览 12 评论 0原文

我有 2 个应用程序想要通过 .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(....);
    }  
}

请求者代码

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

思念满溢 2024-08-09 16:01:12

doIt() 中执行 outstream.Write(xml.ToString()) 后,您将尝试从 instream 读取数据。与此同时,您的另一个线程正在 stream.ReadToEnd() 中等待。它会永远等待,因为它不知道你已经写完了。据它所知,您完全可以再次调用 outstream.Write() 来写入更多数据。在您实际从 doIt() 关闭管道之前,ReadToEnd() 调用不会返回。

您可以通过让他们更智能地相互沟通来解决这个问题。例如,您可以将 xml.ToString() 的长度写入管道,然后写入字符串。然后在您的阅读器线程中,您首先读取长度,然后读取 msg_in,仅读取您期望发送的确切字节数,在读取完所有字节后立即停止,而不是等待管道被发送关闭。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文