2010-09-27 11 views
6

Tôi không thể tìm thấy một ví dụ điển hình về cách tạo một bộ lắng nghe ống có thể tái sử dụng được chạy không đồng bộ. Tôi có thể làm cho người nghe tái sử dụng:Làm cách nào để bạn triển khai trình nghe ống có tên có thể tái sử dụng chạy không đồng bộ?

NamedPipeServerStream pipeServer = new NamedPipeServerStream("MyPipe", PipeDirection.InOut); 

    while (true) 
    { 
      pipeServer.WaitForConnection(); 

      StreamReader reader = new StreamReader(pipeServer); 

      MessageBox.Show(reader.ReadLine()); 

      pipeServer.Disconnect(); 
    } 

và tôi có thể làm cho một người biết lắng nghe asychronous:

NamedPipeServerStream pipeServer = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous); 

    pipeServer.BeginWaitForConnection((a) => 
    { 
     pipeServer.EndWaitForConnection(a); 

     StreamReader reader = new StreamReader(pipeServer); 
     MessageBox.Show(reader.ReadLine()); 

    }, null); 

Nhưng tôi dường như không thể có được cả hai đi. Có một ví dụ tốt cho điều này? Tôi cũng lo ngại về các thư được gửi một phần, vì tôi tin rằng đó là một vấn đề với các liên lạc không đồng bộ như thế này.

Cập nhật: Tôi gần hơn một chút.

pipeServer = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous); 

pipeServer.BeginWaitForConnection((a) => 
{ 
    pipeServer.EndWaitForConnection(a); 

    StreamReader reader = new StreamReader(pipeServer); 

    while (running) 
    { 
     String text = reader.ReadLine(); 

     if (String.IsNullOrEmpty(text) == false) 
     { 
      MessageBox.Show(text); 
     } 
    } 

    MessageBox.Show("Done!"); 

}, null); 

Điều đó sẽ đọc thành công một lần và sẽ tiếp tục lặp lại, với ReadLine trả về một chuỗi trống rỗng sau khi đọc thành công ban đầu. Vì vậy, nó rõ ràng không chặn, và đang cố đọc lại. Vấn đề là nếu tôi gửi cùng một tin nhắn lần thứ hai, nó không được chọn, và người viết ống của tôi nói rằng nó nhận được lỗi 2316 (mặc dù tôi không thể hiểu được điều đó có nghĩa là gì). Tôi nghĩ rằng tôi chỉ cần làm một cái gì đó tương tự như này, nơi các đường ống được làm sạch lên mỗi lần, giống như mẫu mã đầu tiên tôi liệt kê, nhưng tôi đã không nhận được rằng để làm việc được nêu ra.

+0

Mã lỗi hệ thống (ví dụ: Win32 API) có tại đây: http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx Nhưng không có lỗi 2316 ... bạn có chắc chắn không đó là mã lỗi? Bạn có thể bao gồm đầy đủ chi tiết về ngoại lệ (bao gồm cả loại và thông báo không? – Richard

+0

Xin lỗi, tôi không thấy điều này cho đến bây giờ và tôi không còn tạo lỗi nữa. Đây là mã tạo ra nó, vào cuối của nhà văn: if (ống == INVALID_HANDLE_VALUE) \t \t { \t \t \t cout << "lỗi:" << GetLastError(); \t \t} –

+0

hóa ra đó là lỗi 231. 6 là đầu ra từ cái gì khác –

Trả lời

6

Tôi nghĩ rằng tôi đã có nó:

pipeServer = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous); 

Boolean connectedOrWaiting = false; 

Byte[] buffer = new Byte[65535]; 

while (running) 
{ 
    if (!connectedOrWaiting) 
    {     
     pipeServer.BeginWaitForConnection((a) => { pipeServer.EndWaitForConnection(a); }, null); 

     connectedOrWaiting = true; 
    } 

    if (pipeServer.IsConnected) 
    { 
     Int32 count = pipeServer.Read(buffer, 0, 65535); 

     if (count > 0) 
     { 
      UTF8Encoding encoding = new UTF8Encoding(); 
      String message = encoding.GetString(buffer, 0, count); 

      MessageBox.Show(message); 
     } 

     pipeServer.Disconnect(); 

     connectedOrWaiting = false; 
    } 
} 

này sẽ chấp nhận nhiều thông điệp khi họ đến, và sẽ đóng cửa càng sớm càng chạy được thiết lập là false (trong chủ đề khác, rõ ràng). Nó dường như là những gì tôi cần. Ai đó có thể xác minh rằng tôi không làm bất cứ điều gì ngớ ngẩn?

2

I'm also concerned about partially sent messages

Chúng không phải là vấn đề với NamedPipes sử dụng API gốc (Win32), vì vậy tôi rất nghi ngờ chúng là vấn đề khi sử dụng .NET. Tuy nhiên trong native documentation nó nói:

Data is written to the pipe as a stream of messages. The pipe treats the bytes written during each write operation as a message unit. The GetLastError function returns ERROR_MORE_DATA when a message is not read completely. This mode can be used with either PIPE_READMODE_MESSAGE or PIPE_READMODE_BYTE.

(Lưu ý ERROR_MORE_DATA là 234.)

Các tài liệu cũng cho biết, đối với lá cờ FILE_FLAG_OVERLAPPED (tương đương với mẹ đẻ của PipeOptions.Asynchronous):

Overlapped mode is enabled. If this mode is enabled, functions performing read, write, and connect operations that may take a significant time to be completed can return immediately.

tôi đã luôn sử dụng các hoạt động IO không đồng bộ với các đường ống không đồng bộ (tức là Stream.BeginRead), nhưng điều này không có nghĩa là mất chức năng của TextReader, nhưng sau đó PipeTransmissionMode.Message được định nghĩa trong điều kiện truyền các nhóm byte anyway.

+1

. Vâng đó là tốt để biết.Tôi rất cởi mở với BeginRead, nhưng tôi không nghĩ mình đang sử dụng nó đúng. Tôi thiết lập kết nối của tôi, nhưng số lượng byte đọc (sự trở lại từ EndRead) luôn luôn là 0. Bạn có biết một ví dụ hay không? Tốt nhất là một trong đó là tái sử dụng? –