2013-02-12 13 views
5

Aynı makine üzerinde bir sunucu ve istemci işlemi arasında iletişim kurmak için adlandırılmış yöneltmeler kullanmaya çalışıyorum. Sunucu istemciye bir mesaj gönderir, istemci onunla bir şey yapar ve bir sonuç döndürür ve sunucunun sonucu alması beklenir. Burada iki işlem arasında c adlandırılmış yöneltmeler arasında çift yönlü işlem C#

sunucu için kodudur:

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); 
      } 
     } 
    } 
} 

ve burada müşteri için kodudur: satır pipeServer.WaitForPipeDrain üzerine,

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(); 
    } 
} 

Ama sunucu kodunda(); Bir ObjectDisposedException alıyorum ve "kapalı bir boruya erişemiyor" diyor.

Ayrıca sw.AutoFlush öğesini true olarak ayarlarken istemci kodunda da aynı hatayı alıyorum.

Temel olarak C# olarak adlandırılmış dubleks adında bir örnek bulunamadı. Ya buna ya da bir anonim boruya ihtiyacım var, biri okumak için iki boru ve bir ebeveyn ve bir çocuk süreci arasında bir yazı için.

Teşekkürler.

+1

"StreamWriter" i boş bırakmıyor aynı zamanda temel akışı (yani, pipeServer'ınız) kapatmıyor mu? –

+0

WCF, adlandırılmış boruların üstünde çalışarak size bir ton çalışma sağlayacaktır. –

+0

Bir örnek görebilirmiyim lütfen? – jambodev

cevap

7

Sorun, temel Akışı kapat (burada sizin borunuz) olan StreamWriter kullanımının engellenmesidir. Eğer bu bloğu kullanmazsanız çalışması gerekir. Johannes Egger belirttiği gibi

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

, StreamWriterDispose() ilgili akışı basması, yani StreamWriter ilk olarak yerleştirilir ve böylece imha etmek için en iç nesne olmalıdır:

aşağıdaki yapabilirdi.

+0

Teşekkürler, bu sorunu çözdü. Kodda bir sorun daha vardı, bu okuyucular bir süre içinde gerçekleşiyordu ve sonuç olarak bir çıkmaz vardı, o zamanları değiştirmişlerdi ve şimdi iyi çalışıyorlardı. – jambodev

+0

Benim durumumda, yazar okuyucunun elden çıkarılması gerektiğinde yazarın bertaraf edilmesi önemliydi, çünkü okuyucunun elden çıkarılması sırasında okuyucunun imha edilmesi gerektiğinde, ilk önce boru da bertaraf edilmiş ve yazar temizlenemedi. –

+0

@JohannesEgger iyi nokta. – TGlatzer

İlgili konular