2012-02-07 84 views
0

有時,在某些機器上經常發生並且很少發生,正在使用我的程序的客戶端正在出現「管道正在關閉」異常。這發生在.WaitForConnection()上的NamedPipeServerStream上。之後,應用程序完全崩潰並釋放一個Windows異常。當NamedPipeClientStream將信息傳輸到獨立應用程序時會發生這種情況。管道正在關閉例外

主要功能: 我寫了幾個與NamedPipes一起通信的工具(Office工具欄,服務,獨立.NET應用程序和litle starter exe)。 服務運行始終打開的NamedPipeServerStream(處於狀態.WaitForConnection();),而獨立應用程序也有NamedPipeServerStream。 工具欄和啓動程序.exe與服務進行通信。該服務然後與獨立應用程序。

什麼樣的問題可以釋放管道正在關閉例外? 服務器是否有可能將信息發送到獨立應用程序,但是由於獨立應用程序還沒有準備好或什麼時候關閉了流,每個NamedPipeClientStream怎麼做,如果pipeClient.IsConnected befor我關閉pipeclient一個waitforpipedrain ..

感謝您的幫助

編輯:這裏一個clientstream的pipeserver的

using (NamedPipeClientStream pipeClient = 
     new NamedPipeClientStream(".", pipename, PipeDirection.Out)) 
{ 
    // Wait for a client to connect 
    try 
    {        
     pipeClient.Connect(3000); 

     // send params to the form 
     using (StreamWriter sw = new StreamWriter(pipeClient)) 
     { 
      sw.AutoFlush = true; 
      sw.WriteLine(sendtext); 
     } 
    } 
    // Catch the IOException that is raised if the pipe is 
    // broken or disconnected. 
    catch (Exception e) 
    { 
     if (sid != "") 
     { 
      connections.Remove(conName); 
     } 
     eventLog1.WriteEntry("SendText Fehler 1 " + e.Message); 
    } 
    finally 
    { 
     if (pipeClient.IsConnected) 
     { 
      pipeClient.WaitForPipeDrain(); 
     } 
     pipeClient.Close(); 
     pipeClient.Dispose(); 
    } 

例的例子(即在seperad線程運行)

NamedPipeServerStream pipeServer; 
PipeSecurity pipe_security = CreateSystemIoPipeSecurity(); 
do 
    string pipename = global::TOfficeCenter.Properties.Settings.Default.pipename; 
    string aText = ""; 
    pipeServer = new NamedPipeServerStream(pipename, PipeDirection.In, ONE_INSTANCE, PipeTransmissionMode.Byte, 
            PipeOptions.None, IN_BUF_SIZE, OUT_BUF_SIZE, pipe_security); 
    try 
    { 
     // Verbindung zu TOfficeCenter.exe aufbauen 
     try 
     { 
      IsWaiting = true; 
      pipeServer.WaitForConnection(); 
      IsWaiting = false; 

      using (StreamReader sr = new StreamReader(pipeServer)) 
      { 
       string temp; 
       while ((temp = sr.ReadLine()) != null) 
       { 
        aText = aText + temp; 
       } 
      } 

      try 
      { 
       if (aText == "") 
       { 
        empfang(null); 
       } 
       else 
       { 
        if (aText != "KillPipe") 
        { // XML empfangen 
         XmlDocumentTC xml = new XmlDocumentTC(); 
         xml.LoadXml(aText); 
         empfang(xml); 
        } 
       } 
      } 
      catch (Exception) 
      { 
       empfang(null); 
      } 
     } 
     catch 
{........... 
}  
    } 

    catch (Exception e) 
    {........... 
    } 

} while (running); 

pipeServer.Close(); 
+0

您確定沒有在其中一個應用程序中偶然關閉管道嗎? – svick 2012-02-07 11:58:49

+0

我想在客戶端數據導致在服務器中的異常。這是未處理的,以便服務器關閉,在客戶端中產生該異常。改進服務器中的異常日誌記錄以更好地診斷此問題,實現AppDomain.UnhandledException事件。 – 2012-02-07 12:09:42

+0

感謝您的回答。 – user1194383 2012-02-07 12:30:01

回答

0

這可能是因爲我終於找到了問題..

我發現這個代碼後:

    using (StreamWriter sw = new StreamWriter(pipeClient)) 
        { 
         sw.AutoFlush = true; 
         sw.WriteLine(sendtext); 
        } 

的pipeClient.IsConnected();直接返回false,所以它永遠不會進入WaitForPipeDrain。我現在這樣做了,希望客戶端在服務器讀完之前不關閉連接。

    using (StreamWriter sw = new StreamWriter(pipeClient)) 
        { 
         sw.AutoFlush = true; 
         sw.WriteLine(sendtext); 
         pipeClient.WaitForPipeDrain(); 
        } 

您是否認爲可以解決問題?由於我做到了,我從來沒有在兩臺測試機器上發現錯誤。但無論如何錯誤很少發生..

0

我的使用是有點不同,但我會包括和服務器線程,因爲它是被大多從MSDN頁面目前黑客:

MSDN: How to Use Named Pipes

不知道是否需要「WaitForPipeToDrain()」,但我把它從你的代碼:)

我認爲每次重置管道服務器是清理我的IOException。

int threadId = Thread.CurrentThread.ManagedThreadId; 
    bool sentinel = true; 

    while (sentinel) 
    { 
     NamedPipeServerStream pipeServer = 
      new NamedPipeServerStream("shapspipe", PipeDirection.InOut, 1); 
     // Wait for a client to connect 
     pipeServer.WaitForConnection(); 

     Console.WriteLine("Client connected on thread[{0}].", threadId); 
     try 
     { 
      // Read the request from the client. Once the client has 
      // written to the pipe its security token will be available. 

      StreamString ss = new StreamString(pipeServer); 

      // Verify our identity to the connected client using a 
      // string that the client anticipates. 

      ss.WriteString("I am the one true server!"); 
      string message = ss.ReadString(); 

      Console.WriteLine("received from client: " + message); 

      ss.WriteString("echo from server: " + message); 

      Console.WriteLine("Received from client: {0} on thread[{1}] as user: {2}.", 
       message, threadId, pipeServer.GetImpersonationUserName()); 
     } 
     // Catch the IOException that is raised if the pipe is broken 
     // or disconnected. 
     catch (IOException e) 
     { 
      Console.WriteLine("ERROR: {0}", e.Message); 
     } 
     pipeServer.WaitForPipeDrain(); 
     pipeServer.Close(); 
    }