Как продолжить отправку / чтение сообщений из именованных каналов / потоков - PullRequest
4 голосов
/ 26 февраля 2012

Я учу себя использовать каналы, и у меня есть два приложения, одно с классом PipeServer и одно с классом PipeClient (показано ниже). Серверное приложение создает экземпляр PipeServer и имеет текстовое поле, которое вызывает метод WriteMessage при изменении текстового поля. Клиентское приложение создает экземпляр PipeClient, устанавливает для MessageReadEvent метод, который заполняет текстовое поле заданным сообщением, а затем вызывает метод ReadMessages.

При первом вызове метода ReadMessages он попадает в sr.ReadLine () и ожидает там, пока не будет получено сообщение. После получения сообщения следующий вызов sr.ReadLine () естественным образом возвращает ноль и продолжает выход из метода.

В этот момент любые дальнейшие вызовы 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 Ответ

4 голосов
/ 26 февраля 2012

StreamReader закрывает поток, переданный ему после утилизации, и вы удаляете StreamReader в конце блока using (StreamReader sr = new StreamReader(_pipeClient)).

Вы можете создать 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);
    }
...