System.IO.Exception: канал сломан на стороне клиента

У меня есть два приложения Windows, и я использую именованные каналы для отправки и получения списков данных между ними. С механизмом сериализации/десериализации с использованием класса BinaryFormatter.

Сервер:

  static void StartServer()
    {
        var server = new NamedPipeServerStream("PipesEnroll", PipeDirection.InOut);

            while (true)
            {
                StreamReader reader = new StreamReader(server);
                StreamWriter writer = new StreamWriter(server);
                string terminalTemplate;
                string matcherTemplate;
                int mathVersionNumber = 9;
                int numberFingers;
                BinaryFormatter formatterDeserialize = new BinaryFormatter();
                List<byte[]> retrievedList = (List<byte[]>)formatterDeserialize.Deserialize(reader.BaseStream);
                bool isOk = Enroll.EnrollWithoutWCF(retrievedList, mathVersionNumber, out terminalTemplate, out matcherTemplate, out numberFingers);
                List<String> sendList = new List<string>();
                sendList.Add(isOk.ToString());
                sendList.Add(terminalTemplate);
                sendList.Add(matcherTemplate);
                sendList.Add(numberFingers.ToString());
                BinaryFormatter formatterSerialize = new BinaryFormatter();
                formatterSerialize.Serialize(writer.BaseStream, sendList);
                server.Disconnect();
       }

Клиент:

                    using (var client = new NamedPipeClientStream(".", "PipesEnroll", PipeDirection.InOut))
                        {
                            client.Connect();
                            StreamReader reader = new StreamReader(client);
                            StreamWriter writer = new StreamWriter(client);

                                BinaryFormatter formatterSerialize = new BinaryFormatter();
                                formatterSerialize.Serialize(writer.BaseStream, images);
                                // writer.Write(stream);
                                // writer.Flush();
                                BinaryFormatter formatterDeserialize = new BinaryFormatter();
                                List<String> retrievedList = (List<String>)formatterDeserialize.Deserialize(reader.BaseStream);
                                bool isOK = Convert.ToBoolean(retrievedList[0]);
                                string terminalTemplate = retrievedList[1];
                                string matcherTemplate = retrievedList[2];
                                int numberFingers = Convert.ToInt32(retrievedList[3]);

}

Но при выполнении formatterSerialize.Serialize(writer.BaseStream, images); в режиме отладки.

Есть ли у кого-нибудь предложения о том, как избежать этой проблемы?


person Andrei Karcheuski    schedule 21.10.2014    source источник
comment
Я действительно не знаю, в чем проблема. И вы не предоставили отлаживаемый пример для работы, поэтому нет возможности провести расследование. Но я нашел еще один пример SO с именованными каналами, где они вызывали WaitForConnection() на сервере, прежде чем они начали пытаться читать из потока. Вы можете попробовать добавить это здесь. Кроме того, вам следует просто избавиться от объектов StreamReader и StreamWriter. Вы их не используете, и было бы плохой идеей пытаться смешивать их с прямым чтением/записью из/в базовые потоки.   -  person Peter Duniho    schedule 21.10.2014
comment
Добавьте функцию WaitForPipeDrain() перед отключением.   -  person Hans Passant    schedule 21.10.2014
comment
Большое спасибо за ответы. Действительно, я просто забыл WaitForConnection() на стороне сервера.   -  person Andrei Karcheuski    schedule 21.10.2014


Ответы (1)


StreamWriter принадлежит NamedPipeClientStream. Если NamedPipeClientStream удаляется, часть его процесса также удаляет StreamWriter. Если по какой-либо причине StreamWriter закрыт/удален в любой другой части кода, результатом будет разрыв канала.

1) Убедитесь, что formatterSerialize.Serialize не закрывает StreamWriter.

2) Также не забудьте сбросить StreamWriter перед выходом из использования NamedPipeClientStream.

person Yonathan Druck    schedule 17.01.2016
comment
Прежде чем ответить на старый вопрос, на который еще нет ответов, вы также должны проверить комментарии, чтобы увидеть, упоминается ли там решение проблемы, и проблема решена за это время. - person hotzst; 17.01.2016
comment
Я не согласен - много. Хотя оба предложения хороши и, в конечном счете, сделанное предположение было правильным - оно не является таким кратким и полным ответом, как этот. Кроме того, ответы не относятся к комментариям. - person jinzai; 18.07.2016