2013-02-12 25 views
5

Tôi đang cố gắng sử dụng các đường ống được đặt tên để giao tiếp giữa máy chủ và quy trình ứng dụng khách trên cùng một máy. máy chủ gửi một tin nhắn cho khách hàng, khách hàng làm một cái gì đó với nó và trả về một kết quả, và máy chủ được cho là để có được kết quả.hoạt động song công giữa hai quy trình sử dụng các đường ống có tên trong C#

đây là mã cho server:

using System; 
using System.IO; 
using System.IO.Pipes; 

class PipeServer 
{ 
    static void Main() 
    { 
     using (NamedPipeServerStream pipeServer = 
      new NamedPipeServerStream("testpipe", PipeDirection.InOut)) 
     { 
      Console.WriteLine("NamedPipeServerStream object created."); 

      // Wait for a client to connect 
      Console.Write("Waiting for client connection..."); 
      pipeServer.WaitForConnection(); 

      Console.WriteLine("Client connected."); 
      try 
      { 
       // Read user input and send that to the client process. 
       using (StreamWriter sw = new StreamWriter(pipeServer)) 
       { 
        sw.AutoFlush = true; 
        Console.Write("Enter text: "); 
        sw.WriteLine(Console.ReadLine()); 
       } 

       pipeServer.WaitForPipeDrain(); 

       using (StreamReader sr = new StreamReader(pipeServer)) 
       { 
        // Display the read text to the console 
        string temp; 

        // Wait for result from the client. 
        while ((temp = sr.ReadLine()) != null) 
        { 
         Console.WriteLine("[CLIENT] Echo: " + temp); 
        } 
       } 

      } 
      // Catch the IOException that is raised if the pipe is 
      // broken or disconnected. 
      catch (IOException e) 
      { 
       Console.WriteLine("ERROR: {0}", e.Message); 
      } 
     } 
    } 
} 

và đây là mã cho khách hàng:

using System; 
using System.IO; 
using System.IO.Pipes; 

class PipeClient 
{ 
    static void Main(string[] args) 
    { 
     using (NamedPipeClientStream pipeClient = 
      new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut)) 
     { 

      // Connect to the pipe or wait until the pipe is available. 
      Console.Write("Attempting to connect to pipe..."); 
      pipeClient.Connect(); 

      Console.WriteLine("Connected to pipe."); 
      Console.WriteLine("There are currently {0} pipe server instances open.", 
       pipeClient.NumberOfServerInstances); 
      using (StreamReader sr = new StreamReader(pipeClient)) 
      { 
       // Display the read text to the console 
       string temp; 
       while ((temp = sr.ReadLine()) != null) 
       { 
        Console.WriteLine("Received from server: {0}", temp); 
       } 
      } 


      // send the "result" back to the Parent process. 
      using (StreamWriter sw = new StreamWriter(pipeClient)) 
      { 
       sw.AutoFlush = true; 
       sw.WriteLine("Result"); 
      } 

      pipeClient.WaitForPipeDrain(); 

     } 
     Console.Write("Press Enter to continue..."); 
     Console.ReadLine(); 
    } 
} 

Nhưng trong mã máy chủ, trên dòng pipeServer.WaitForPipeDrain(); Tôi nhận được một ObjectDisposedException và nó nói "không thể truy cập một đường ống khép kín."

Tôi cũng nhận được cùng một lỗi trong mã máy khách khi thiết lập sw.AutoFlush thành true.

Về cơ bản, tôi không thể tìm thấy ví dụ về ống hai mặt có tên trong C#. Tôi cần điều đó, hoặc một ví dụ về ống anonynous, với hai ống một để đọc và một cho việc viết giữa cha mẹ và một tiến trình con.

Cảm ơn trước.

+1

Không xử lý 'StreamWriter' cũng đóng luồng cơ bản (nghĩa là' pipeServer') của bạn? –

+0

WCF chạy trên đầu trang của các đường ống được đặt tên sẽ giúp bạn tiết kiệm rất nhiều công việc. –

+0

Tôi có thể xem ví dụ ở đâu? – jambodev

Trả lời

7

Vấn đề là khối sử dụng của StreamWriter, sẽ đóng Luồng cơ bản (đây là ống của bạn ở đây). Nếu bạn không sử dụng khối đó, nó sẽ hoạt động.

Bạn có thể làm như sau:

using (var pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut)) 
using (var streamReader = new StreamReader(pipeServer)) 
using (var streamWriter = new StreamWriter(pipeServer)) 
{ 
    // ... Your code .. 
} 

Như Johannes Egger chỉ ra, StreamWriter xả suối trên Dispose(), vì vậy StreamWriter nên được xử lý đầu tiên và do đó là bên trong hầu hết các đối tượng để xử lý.

+0

Cảm ơn, đã giải quyết được vấn đề. đã có thêm một vấn đề trong mã, mà Reads đã diễn ra trong một vòng lặp while và kết quả là đã có một bế tắc, thay đổi trong khi để nếu và nó hoạt động tốt ngay bây giờ. – jambodev

+0

Trong trường hợp của tôi điều quan trọng là người viết phải xử lý sau khi người đọc vì nhà văn đã xả nước khi xử lý, nhưng khi người đọc được xử lý trước thì ống cũng được xử lý và nhà văn không thể tuôn ra. –

+0

@JohannesEgger điểm tốt. – TGlatzer

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