2016-03-30 4 views
3

を閉じている私は心がある、C#で簡単な非同期NamedPipeStreamServerプロセスを書かれている:NamedPipeServerStream.BeginWaitForConnectionはSystem.IO.Exceptionで失敗します。パイプは

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

私もシンプルなクライアントを書かれていますそれのための。 (非同期ではありません)、クライアントはパイプオープンして終了以上何もしません:私は、サーバーを起動し、クライアント、または複数のクライアントを起動すると

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

を、すべてが正常に動作するようです。

サーバーを起動せずにクライアントを起動すると、サーバーを起動するまでクライアントがConnect()コールでハングしますが、サーバーを起動するとサーバーはSystem.IO.ExceptionでクラッシュしますBeginWaitForConnection()コールで「パイプが閉じられています」と表示されます。

BeginWaitForConnection()で "パイプが閉じられました"というエラーが発生しましたが、すべて同じNamedPipeServerStreamインスタンスで2番目のBeginWaitForConnection()呼び出しを試行したことが原因です。それはここで起こっていることではありません - 私はBeginWaitForConnection()呼び出しごとに別のNamedPipeServerStreamインスタンスを作成し、そうでない場合でも最初のBeginWaitForConnection()呼び出しで失敗しています。

何か間違っていますか?または、これはちょうど普通です - サーバーが起動するのを待っている名前付きパイプクライアントは、サーバーの最初のBeginWaitForConnection()呼び出しで「パイプが閉じられています」原因になりますか?

例外を吸収して別のBeginWaitForConnection()を実行すると、サーバが起動するのを待っていたすべてのクライアントに対して例外が発生しますが、その後、サーバーは正常に動作するように見えます。

EDIT:ここHandleConnection方法ですが、私はそれも、このコードに当たるとは思わない:

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

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

HandleConnectionメソッドを表示できますか? ConnectNamedPipe()が呼び出される前にクライアントが接続を要求した場合、イベント(AsyncWaitHandleを待つ)を設定する必要があると思います。 – alexm

+0

alexm、確かに、私は私の質問の最後にそれを加えました。しかし、私はそれが最初にそのコードに当てはまるとは思わない。 –

答えて

2

それは完全にサーバーによって処理される前に、クライアントが接続を閉じることが表示されます。 clientStream.Connect()の直後にclientStream.Dispose()が呼び出され、確立しようとしていた接続が終了するために発生します。 ヒント:clientStream.Connect()の直後にThread.Sleep(100)を追加してみてください。

私は何か間違っていますか?または、これはちょうど正常です - 名前付きパイプ クライアントがサーバーの起動を待っている場合、サーバーの最初のBeginWaitForConnection()呼び出しで "パイプ が閉じられています"

かかわらず、クライアントがサーバ・コードは、正常なサーバのパイプハンドルを破棄にIOException を引くことにより、この一連のイベントを処理することができるはず何の。

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; 
    } 
関連する問題