2009-08-20 7 views
2

Ich habe 2 Apps, die ich über Named Pipes auf .NET 3.5 kommunizieren möchte. Es ist ein Request/Response-Paradigma, bei dem die Daten als XML übertragen werden, um mein Leben einfacher zu machen. Es gibt eine Listener-App und eine App, die Anfragen an die Pipe sendet. Ich versuche, dafür eine bidirektionale Pipe zu verwenden. Das Problem, das ich habe, ist, dass der Aufruf von StreamReader.ReadToEnd() scheint nicht zurückzukehren. Was kann ich tun, um das zu beheben?bidirektionale Named Pipe Frage

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(....); 
    } 
} 

Anforderer 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; 
} 

Antwort

6

Nachdem Sie outstream.Write(xml.ToString()) in doIt() Sie dann versuchen, von instream zu lesen. Inzwischen wartet Ihr anderer Thread in stream.ReadToEnd(). Es wird ewig warten, weil es nicht weiß, dass du fertig schreibst. Soweit es bekannt ist, könnte man sehr gut outstream.Write() anrufen, um noch ein paar Daten zu schreiben. Der ReadToEnd() Aufruf wird nicht zurückgeben, bis Sie tatsächlich die Pipe von doIt() schließen.

Sie können dies umgehen, indem Sie sie ein wenig intelligenter miteinander kommunizieren lassen. Sie könnten zum Beispiel die Länge xml.ToString() in die Pipe schreiben und dann die Zeichenfolge schreiben. Dann lesen Sie in Ihrem Leser-Thread zuerst die Länge und lesen dann msg_in, lesen nur die genaue Anzahl der Bytes, die Sie voraussichtlich gesendet werden, stoppen, sobald Sie sie alle lesen, anstatt zu warten, bis die Pipe geschlossen wird.