2012-03-02 12 views
5

堅牢なタイムアウト管理を使用して名前付きパイプIPCを実装する最善の方法を見つけるのに苦労しています。私は、接続の確立時にタイムアウトを意味するのではなく、読み書きストリームでタイムアウトを意味します。名前付きパイプの例読み取り/書き込みタイムアウトを使用するIPC

私が見つけたすべての例には、タイムアウトの実装がありません。

誰かが私に実例を教えてくれますか、これを示す例を教えてください。

+0

名前付きパイプを使用しようとしていますか、名前付きパイプでWCFを使用していますか? –

+0

@AdamGritt:名前付きパイプ。 –

答えて

3

NamedPipeClientStream.BeginReadNamedPipeClientStream.BeginWriteで非同期の読み書きをするのはおそらく何でしょうか。一定時間の間、データが送信されなかったか、または受信されなかったかを検出するためにタイマーが使用されます。

データが送受信されるたびに、DateTimeフィールドはDateTime.Nowに設定され、タイマーの実行ごとにそのフィールドがチェックされ、タイムアウトが発生したかどうかが判断されます。いずれかが発生した場合は、NamedPipeClientStreamを閉じて、NamedPipeClientStream.EndReadNamedPipeClientStream.EndWriteの例外をキャッチすることができます。

私は実用的な例はまだ用意されていませんが、必要に応じて作業を開始します。うまくいけば、これはあなたを助けてくれるでしょう。


これは非常に荒いコード例です。 IDisposableを実装し、書き込みメソッドを追加するなど、もっと多くのことを行う必要があります。しかし、これはアイデアを説明するのに役立つはずです。このコードを直接使用するのではなく、モデルとして使用するのが最善の方法です。コードをテストして読み込みを確認しました。

//this is a very rough model of how to do it. a lot more would need to be implemented 
//i'm assuming you plan to continuously read from it. i can think up another example if you're not 
//also not thread safe 
public class MyPipeClient 
{ 
    NamedPipeClientStream PipeClient = new NamedPipeClientStream("testpipe1"); 
    Timer TimeoutTimer; 
    DateTime LastRead; 
    const int TimeoutSeconds = 120; //2 mins 

    //will connect and start receiving 
    public void Connect() 
    { 
     PipeClient.Connect(); 
     LastRead = DateTime.Now; 

     TimeoutTimer = new Timer(TimeoutCheck, this, 0, 1000); //check every second 

     Read(this); 
    } 

    public void Disconnect() 
    { 
     PipeClient.Close(); PipeClient = null; 
     TimeoutTimer.Dispose(); TimeoutTimer = null; 
    } 

    static void Read(MyPipeClient client) 
    { 
     PipeState state = new PipeState(client); 

     try 
     { 
      client.PipeClient.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallback, state); 
     } 
     catch (InvalidOperationException) //disconnected/disposed 
     { 
      return; 
     } 
    } 

    static void ReadCallback(IAsyncResult ar) 
    { 
     PipeState state = (PipeState)ar.AsyncState; 
     MyPipeClient client = state.Client; 

     client.LastRead = DateTime.Now; 

     int bytesRead; 

     try 
     { 
      bytesRead = client.PipeClient.EndRead(ar); 
     } 
     catch (IOException) //closed 
     { 
      return; 
     } 

     if (bytesRead > 0) 
     { 
      byte[] data = state.Buffer; 

      //TODO: something 
     } 
     else //i've never used pipes, so i'm assuming this behavior exists with them 
     { 
      client.Disconnect(); 
      return; 
     } 

     Read(client); 
    } 

    static void TimeoutCheck(object state) 
    { 
     MyPipeClient client = (MyPipeClient)state; 

     TimeSpan timeSinceLastRead = DateTime.Now - client.LastRead; 

     if (timeSinceLastRead.TotalSeconds > TimeoutSeconds) 
     { 
      client.Disconnect(); 
     } 
    } 
} 

class PipeState 
{ 
    public byte[] Buffer = new byte[4096]; 
    public MyPipeClient Client; 

    public PipeState(MyPipeClient client) 
    { 
     Client = client; 
    } 
} 
+0

素晴らしい例。私はこれを試してみる。 –

関連する問題