如何继续从命名管道/流中发送/读取消息

Posted

技术标签:

【中文标题】如何继续从命名管道/流中发送/读取消息【英文标题】:How to continue sending/reading messages from named pipes / streams 【发布时间】:2012-02-26 07:44:41 【问题描述】:

我正在自学使用管道,我有两个应用程序,一个是 PipeServer 类,一个是 PipeClient 类(如下所示)。服务器应用程序创建 PipeServer 的一个实例,并具有一个文本框,当文本框更改时,该文本框会调用 WriteMessage 方法。客户端应用创建 PipeClient 的实例,将 MessageReadEvent 设置为使用给定消息填充文本框的方法,然后调用 ReadMessages 方法。

第一次调用 ReadMessages 方法时,它会到达 sr.ReadLine() 并在那里等待,直到收到消息。收到消息后,下一次调用 sr.ReadLine() 自然返回 null 并继续退出该方法。

此时,对 ReadMessages 的任何进一步调用都会给我一个异常,说明管道已关闭。我不确定我是否理解管道关闭的原因。如何保持打开状态?当然,我不必为要发送的每条消息都创建一个新的管道实例吗?

下面是我的 PipeClient 类。如果有帮助,我也可以添加我的 PipeServer 类,但我认为问题出在此处...

    public delegate void MessageReadEventHandler(string message);

    class PipeClient: IDisposable
    
        public event MessageReadEventHandler MessageReadEvent;

        NamedPipeClientStream _pipeClient;

        public PipeClient(string pipeName)
        
            _pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.In);
            _pipeClient.Connect();
        

        public void ReadMessages()
        
            string temp;

            // Is _pipeClient getting disposed when sr gets disposed??
            // I wouldn't think so but I don't understand why I can't seem
            // to use it again after the following using statement is run

            using (StreamReader sr = new StreamReader(_pipeClient))
                while ((temp = sr.ReadLine()) != null)
                    if(MessageReadEvent != null)
                        MessageReadEvent(temp);
        

        public void Dispose()
        
            _pipeClient.Dispose();
        
    

【问题讨论】:

【参考方案1】:

StreamReader 在处理后关闭传递给它的流,并且您在 using (StreamReader sr = new StreamReader(_pipeClient)) 块的末尾处理 StreamReader。

您可以在构造函数中在类级别创建 StreamReader,并在 ReadMessages 方法中使用它

  public PipeClient(string pipeName)
    
        _pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.In);
        _pipeClient.Connect();
        _streamReader = new StreamReader(_pipeClient);
    
  public void ReadMessages()
    
        string temp;



            while ((temp = _streamReader.ReadLine()) != null)
                if(MessageReadEvent != null)
                    MessageReadEvent(temp);
    

【讨论】:

这回答了一个导致另一个问题的问题。万一其他人在这里找到了方法,请转到:benday.com/2008/06/22/… 以获取有关如何执行远优于 Microsoft 提供的内容的完整示例。

以上是关于如何继续从命名管道/流中发送/读取消息的主要内容,如果未能解决你的问题,请参考以下文章

如何从多个命名管道接收消息?

在 Smalltalk 中读取超时的文件流(命名管道)

命名管道问题

为啥在没有人阅读后继续写入命名管道?

使用命名管道将图像从 C++ 发送到 C# 应用程序

命名管道,如何知道在读取端读取的确切字节数。 C++, 视窗