2016-03-30 4 views
3

Ich habe einen einfachen async NamedPipeStreamServer Prozess in C# geschrieben, das Herz, von denen:NamedPipeServerStream.BeginWaitForConnection mit System.IO.Exception fehlschlägt: Das Rohr geschlossen wird

public void Listen() 
{ 
    bool shuttingDown = false; 
    while (!shuttingDown) 
    { 
     NamedPipeServerStream serverStream = 
      new NamedPipeServerStream(
       "bobasdfpipe", 
       PipeDirection.InOut, 
       254, 
       PipeTransmissionMode.Message, 
       PipeOptions.Asynchronous); 

     IAsyncResult connectionResult = 
       serverStream.BeginWaitForConnection(
        this.HandleConnection, 
        serverStream); 

     int waitResult = 
      WaitHandle.WaitAny(
       new[] 
        { 
         this.ShutdownEvent, 
         connectionResult.AsyncWaitHandle 
        }); 
     switch (waitResult) 
     { 
      case 0: 
       // this.ShutdownEvent 
       shuttingDown = true; 
       break; 

      case 1: 
       // connectionResult.AsyncWaitHandle 
       serverStream.EndWaitForConnection(connectionResult); 
       break; 
     } 
    } 
} 

Ich habe auch eine einfache Client geschrieben dafür. Der Client (die nicht asynchron ist) tut nichts anderes, als das Rohr geöffnet und dann die Ausfahrt:

static void Main(string[] args) 
{ 
    using (
     NamedPipeClientStream clientStream = 
      new NamedPipeClientStream(
       ".", 
       "bobasdfpipe", 
       PipeDirection.InOut)) 
    { 
     clientStream.Connect(); 
    } 
} 

Wenn ich den Server auf, starten und dann einen Client oder mehrere Clients starten, alles scheint gut zu funktionieren.

Wenn ich einen Client starte, ohne den Server gestartet zu haben, hängt der Client auf dem Connect() - Aufruf, bis ich den Server starte, aber wenn ich den Server starte, stürzt der Server mit einer System.IO.Exception ab Rufen Sie beim Aufruf von BeginWaitForConnection() auf "Die Pipe wird geschlossen".

Ich habe andere Leute mit "Die Pipe wird geschlossen" -Fehler bei BeginWaitForConnection() gefunden, aber sie werden alle durch einen zweiten BeginWaitForConnection() - Aufruf auf der gleichen NamedPipeServerStream-Instanz verursacht. Das ist nicht, was hier passiert - ich erstelle eine andere NamedPipeServerStream-Instanz für jeden BeginWaitForConnection() - Aufruf, und selbst wenn ich es nicht getan habe, ist der erste BeginWaitForConnection() - Aufruf sowieso fehlgeschlagen.

Mache ich etwas falsch? Oder ist das nur normal - ein Named Pipe-Client, der darauf wartet, dass der Server hochfährt, wird beim ersten BeginWaitForConnection() - Aufruf des Servers "Die Pipe wird geschlossen"?

Ich habe festgestellt, dass, wenn ich nur noch einmal versuchen - dh absorbieren die Ausnahme und eine andere BeginWaitForConnection() - dann bekomme ich eine solche Ausnahme für jeden Client, der auf den Server gewartet hatte, aber nach dem Umgang mit allen von denen scheint der Server danach gut zu funktionieren.

EDIT: Hier ist die HandleConnection Methode, aber ich glaube nicht, es selbst diesen Code hits:

private void HandleConnection(IAsyncResult iar) 
{ 
    NamedPipeServerStream serverStream = 
     (NamedPipeServerStream)iar.AsyncState; 

    Log.Info("So, that happened."); 
    Thread.Sleep(1000); 
    Log.Info("Giving up."); 
} 
+0

Können Sie die HandleConnection-Methode anzeigen? Ich denke, Sie müssen das Ereignis (AsyncWaitHandle, auf das Sie warten) festlegen, wenn die Verbindung vom Client angefordert wurde, bevor ConnectNamedPipe() aufgerufen wurde. – alexm

+0

alexm, sicher, ich habe es am Ende meiner Frage hinzugefügt. Ich glaube nicht, dass es jemals überhaupt diesen Code trifft. –

Antwort

2

Es scheint, dass Kunde die Verbindung schließt, bevor es vollständig von Server gehandhabt wird. Das passiert, weil clientStream.Dispose() direkt nach clientStream.Connect() aufgerufen wird und die Verbindung, die gerade aufgebaut werden sollte, beendet wird. Hinweis: Versuchen Sie Thread.Sleep(100) direkt nach clientStream.Connect() hinzuzufügen.

Mache ich etwas falsch? Oder ist das normal - ein Named Pipe Client, der darauf wartet, dass der Server hochfährt, wird beim ersten BeginWaitForConnection() - Aufruf des Servers "Die Pipe wird geschlossen"?

Unabhängig davon, was der Client führt der Server-Code sollte diese Sequenz von Ereignissen graziös handhaben können von IOException und fangen die Pipehandle des Servers zu verwerfen.

NamedPipeServerStream serverStream = 
     new NamedPipeServerStream(
      "bobasdfpipe", 
      PipeDirection.InOut, 
      254, 
      PipeTransmissionMode.Message, 
      PipeOptions.Asynchronous); 

    try 
    { 
     IAsyncResult connectionResult = serverStream.BeginWaitForConnection(
       this.HandleConnection, 
       serverStream); 


     int waitResult = 
      WaitHandle.WaitAny(
       new[] 
       { 
        this.ShutdownEvent, 
        connectionResult.AsyncWaitHandle 
       }); 
     switch (waitResult) 
     { 
      case 0: 
      // this.ShutdownEvent 
      shuttingDown = true; 
      break; 

      case 1: 
      // connectionResult.AsyncWaitHandle 
       serverStream.EndWaitForConnection(connectionResult); 
       break; 
     }  

    } 
    catch(IOException) 
    { 
     // Connection terminated by client, close server pipe's handle 
     serverStream.Close(); 
     continue; 
    } 
Verwandte Themen