2009-08-20 15 views
2

.NET 3.5で名前付きパイプ経由で通信する2つのアプリケーションがあります。そのリクエスト/レスポンスのパラダイムで、データを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; 
} 

答えて

6

あなたはdoIt()outstream.Write(xml.ToString())を実行した後、あなたが、その後instreamから読み取るしようとします。一方、他のスレッドはstream.ReadToEnd()で待機しています。あなたが書いたことを知らないので、それは永遠に待つでしょう。あなたが知っている限り、もう一度outstream.Write()と呼んでもう少しデータを書くことができます。実際にパイプを閉じるまでdoIt()からReadToEnd()コールは返されません。

これを回避するには、お互いをより賢く通信させることができます。たとえば、長さをxml.ToString()としてパイプに書き込んだ後、その文字列を書き込むことができます。あなたのリーダースレッドでは、最初に長さを読み取ってから、msg_inを読んで、送られると予想される正確なバイト数だけを読んで、パイプが閉じられるのを待つのではなく、それらをすべて読んですぐに停止します。

関連する問題