双向命名管道问题
我有 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在
doIt()
中执行outstream.Write(xml.ToString())
后,您将尝试从instream
读取数据。与此同时,您的另一个线程正在stream.ReadToEnd()
中等待。它会永远等待,因为它不知道你已经写完了。据它所知,您完全可以再次调用outstream.Write()
来写入更多数据。在您实际从doIt()
关闭管道之前,ReadToEnd()
调用不会返回。您可以通过让他们更智能地相互沟通来解决这个问题。例如,您可以将
xml.ToString()
的长度写入管道,然后写入字符串。然后在您的阅读器线程中,您首先读取长度,然后读取msg_in
,仅读取您期望发送的确切字节数,在读取完所有字节后立即停止,而不是等待管道被发送关闭。After you do
outstream.Write(xml.ToString())
indoIt()
you then try to read frominstream
. Meanwhile your other thread is waiting instream.ReadToEnd()
. It will wait forever because it doesn't know that you're done writing. As far as it knows you could very well calloutstream.Write()
again to write some more data. TheReadToEnd()
call is not going to return until you actually close the pipe fromdoIt()
.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 readmsg_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.