2012-03-02 21 views
5

Tôi đang đấu tranh với việc tìm cách tốt nhất để triển khai các đường ống có tên IPC với quản lý thời gian chờ mạnh mẽ. Tôi không có nghĩa là thời gian chờ trên việc thiết lập một kết nối nhưng thời gian chờ trên dòng đọc/ghi.Ví dụ tên ống IPC với thời gian chờ đọc/ghi

Tất cả các ví dụ tôi thấy không có triển khai thời gian chờ.

Ai đó có thể cho tôi ví dụ làm việc và/hoặc chỉ cho tôi một ví dụ cho thấy điều này không?

+0

Bạn đang cố gắng sử dụng Ống có tên thẳng hoặc bạn đang xem sử dụng WCF trên Ống có tên? –

+0

@AdamGritt: ống thẳng có tên. –

Trả lời

3

Điều bạn có thể phải làm là đọc và viết không đồng bộ với NamedPipeClientStream.BeginReadNamedPipeClientStream.BeginWrite; một bộ đếm thời gian sẽ được sử dụng để phát hiện khi dữ liệu chưa được gửi hoặc nhận trong một khoảng thời gian.

Bất cứ khi nào dữ liệu được gửi hoặc nhận, trường DateTime sẽ được đặt thành DateTime.Now và mỗi lần thực hiện bộ hẹn giờ sẽ kiểm tra trường đó để xác định xem thời gian chờ có xảy ra hay không. Nếu xảy ra, NamedPipeClientStream có thể bị đóng và các trường hợp ngoại lệ từ NamedPipeClientStream.EndReadNamedPipeClientStream.EndWrite có thể bị phát hiện.

Tôi chưa có ví dụ làm việc, nhưng tôi sẽ làm việc trên một ví dụ nếu bạn cần. Hy vọng rằng điều này sẽ giúp bạn ra ngoài trong thời gian có ý nghĩa.


Đây là một số mã ví dụ rất thô. Sẽ cần nhiều hơn nữa, chẳng hạn như thực hiện IDisposable và thêm phương thức ghi. Điều này sẽ giúp minh họa ý tưởng, mặc dù. Nó có lẽ sẽ tốt nhất để sử dụng mã này như là một mô hình, thay vì sử dụng nó trực tiếp. Tôi đã kiểm tra mã để xem nó có đọc hay không.

//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

Ví dụ tuyệt vời; Tôi sẽ thử cái này –

Các vấn đề liên quan