2012-03-02 2 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

그레이트보기; 나는 이것을 시도 할 것이다. –

관련 문제