2012-02-04 25 views
8

名前付きパイプを初めて使用しようとしています。NamedPipeServerStream.EndWaitForConnection()は使用時にハングするだけです

EndWaitForConnectionが BeginWaitForConnectionへのすべての呼び出しのために1回だけ呼び出さなければなりません:hereを発見したMSのドキュメントでは、と述べています。

私は良いプログラマーになり、ドキュメントに従おうとしていますが、EndWaitForConnection()は、使用すると無期限にハングアップします。

だから、私は問題ではなくノーサイコロを分離することができればそう見最低限に私のコードをストリップダウン。私が書いたクラスの中から次のコードを取り出しました。

private void WaitForConnectionCallBack(IAsyncResult result) 
{ 

} 

public void Start() 
{ 
    var tempPipe = new NamedPipeServerStream("TempPipe", 
              PipeDirection.In, 
              254, 
              PipeTransmissionMode.Message, 
              PipeOptions.Asynchronous); 

    IAsyncResult result = tempPipe.BeginWaitForConnection(
            new AsyncCallback(WaitForConnectionCallBack), this); 

    tempPipe.EndWaitForConnection(result); // <----- Hangs on this line right here 
} 

1)はなぜそれはEndWaitForConnection()にハングアップするん:それはすぐに、パイプの接続を待機して始まり、その配管の接続を待機して停止しようとしているので、私はそれを変更しましたか?接続を確立する前にサーバーをシャットダウンする場合は、このBeginWaitForConnection()コールバックをどうすれば元に戻すことができますか?

2)のは、私は上記の問題を持っていなかったと仮定しましょう。 2人のクライアントが名前付きパイプに非常に迅速に接続しようとするとどうなりますか?

それぞれのコールバック呼び出しを取得するか、最初の接続通知を受け取るのを待つ必要がありますか?EndWaitForConnection()を呼び出してからWaitForConnectionCallBack()にもう一度呼び出して、次のクライアントのリスニングを再度開始しますか?私は十分に速く接続リスナーを設定していない可能性があるので

後者は、私には競合状態のように思えます。

+0

この呼び出しは、コールバックメソッド(WaitForConnectionCallBack)でのみ使用する必要があります。 tempPipe.Close()を呼び出してキャンセルします。 –

+0

はい、私はその結論に自分自身が起こったのです。 tempPipe.Close()を呼び出すと、直ちにコールバックルーチンが呼び出されることがわかりました。問題は、直ちにEndWaitForConnectionを呼び出すように設定していましたが、パイプが閉じて以来、例外がスローされます。だから、私はtryステートメントをラップし、catchステートメントには何もしなければならなかった。これは正しい解決策ですか?それはあなたが捕まえなければならないあなたのコールバックで例外を強制することを知って、パイプを閉じるために私に少しうっすらそうです。 – Ultratrunks

+0

これは完全に正常です。 –

答えて

8

次のように、私のために働いている解決策の基本骨格は次のとおりです。ここで

private void WaitForConnectionCallBack(IAsyncResult result) 
{ 
    try 
    { 
     PipeServer.EndWaitForConnection(result); 

     /// ... 
     /// Some arbitrary code 
     /// ... 
    } 
    catch 
    { 
     // If the pipe is closed before a client ever connects, 
     // EndWaitForConnection() will throw an exception. 

     // If we are in here that is probably the case so just return. 
     return; 
    } 
} 

は、サーバーコードです。

public void Start() 
{ 
    var server= new NamedPipeServerStream("TempPipe", 
              PipeDirection.In, 
              254, 
              PipeTransmissionMode.Message, 
              PipeOptions.Asynchronous); 

    // If nothing ever connects, the callback will never be called. 
    server.BeginWaitForConnection(new AsyncCallback(WaitForConnectionCallBack), this); 

    // ... arbitrary code 

// EndWaitForConnection() was not the right answer here, it would just wait indefinitely 
// if you called it. As Hans Passant mention, its meant to be used in the callback. 
// Which it now is. Instead, we are going to close the pipe. This will trigger 
// the callback to get called. 

// However, the EndWaitForConnection() that will excecute in the callback will fail 
// with an exception since the pipe is closed by time it gets invoked, 
// thus you must capture it with a try/catch 

    server.Close(); // <--- effectively closes our pipe and gets our 
         //  BeginWaitForConnection() moving, even though any future 
         //  operations on the pipe will fail. 
} 
+0

FYI読み取り専用の名前付きパイプ(NamedPipeClientStreamクラス)のMessageModeを有効にする場合の[C#UnauthorizedAccessException](http://stackoverflow.com/questions/32739224/c-sharp-unauthorizedaccessexception-when-enabling-messagemode-for-read-only -name) 'Message'モードの使用に関する他の情報については、 – OmegaMan

関連する問題