Bidirectional named pipe question
I have 2 applications that I want to communicate with via named pipes on .NET 3.5. Its request / response paradigm with data passed as XML makes my life easier. There is a listener application and an application that sends requests to the channel. I am trying to use a bi-directional tube for this. The problem is that the call to StreamReader.ReadToEnd () doesn't 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;
}
source to share
After you complete outstream.Write(xml.ToString())
in doIt()
, try reading instream
. Meanwhile, your other thread is waiting at stream.ReadToEnd()
. He will wait forever because he doesn't know that you have finished writing. As far as we know, you can call very well outstream.Write()
to write some more data. The call ReadToEnd()
will not return until you actually close the channel from doIt()
.
You can get around this by making them communicate with each other a little smarter. For example, you can write the length xml.ToString()
to a pipe and then write the string. Then in your reader's stream, you read the length first and then read msg_in
, only reading the exact number of bytes you expect to send, stopping as soon as you read them, rather than waiting for the pipe to close.
source to share