2012-08-13 79 views
4

我只是在學習WCF,嘗試不同的事情。使用NamedPipesBinding獲取PipeException(管道正在關閉)WCF服務

我已經設置了以下服務:

[ServiceBehavior(IncludeExceptionDetailInFaults = true , 
    InstanceContextMode = InstanceContextMode.Single)] 
    public class TestService : ITestService 
    { 
     // This operation is defined as OneWay. 
     public void Throws() 
     { 
      throw new ArgumentException(); 
     } 
    } 

我用它從我的客戶像這樣:

var baseAddress = new Uri("net.pipe://localhost/hello"); 

// Create the ServiceHost. 
using (ServiceHost host = new ServiceHost(typeof(TestService), baseAddress)) 
{ 
    var netBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None); 
    host.AddServiceEndpoint(typeof(ITestService), netBinding, baseAddress); 
    host.Open(); 

    Console.WriteLine("The service is ready at {0}", baseAddress); 

    // Create client channel. 
    var channel = ChannelFactory<ITestService>.CreateChannel(netBinding, new EndpointAddress(baseAddress)); 

    ((ICommunicationObject)channel).Open(); 

    try 
    { 
     foreach (var i in Enumerable.Range(0, 5000)) 
     { 
      // channel dies after a few attempts. 
      channel.Throws(); 
     } 
    } 

的方法拋出定義爲IsOneWay =真,這意味着它不會傳播任何消息給客戶端(包括錯誤)。

在循環中運行時,通信對象在一些運行後會發生故障。 我無法弄清楚這個原因。

異常的詳細信息:

System.ServiceModel.CommunicationException:有一個錯誤寫 到管道:管道被關閉。 (232,0xe8)。 ---> System.IO.PipeException:寫入管道時發生錯誤: 管道正在關閉。 (232,0xe8)。在在 System.ServiceModel.Channels.PipeConnection.Write(字節[]緩衝 System.ServiceModel.Channels.PipeConnection.StartSyncWrite(字節[] 緩衝器,的Int32偏移的Int32大小,對象&保持器),的Int32 偏移的Int32大小,布爾眼前,時間跨度超時,BufferManager bufferManage R)---內部異常堆棧跟蹤的結尾---

需要注意的是,如果我改變身體的方法拋出別的東西,像Console.WriteLine,一切運行良好。

編輯:我已經上傳示例項目到我的SkyDrive:http://sdrv.ms/NumUbR

如果有人想在本地編譯它,看看它的表現一樣。

+0

如果連接出現問題,單向操作仍可能失敗,等等,直到服務收到整個消息。另外,我相信託管服務並在同一線程上調用客戶端通道可能會產生一些有趣的結果。 – 2012-08-13 17:02:52

+0

據我所知,該服務未託管在同一線程中。 WCF負責旋轉額外的線程來監視傳入呼叫等。調用ServiceHost。打開塊直到服務主機打開,然後繼續。 – 2012-08-13 17:33:27

+0

另外,這裏的連接在同一臺機器上,我不確定這個小樣本中會出現什麼問題。 – 2012-08-13 17:33:54

回答

4

您只是在某個點上超出了可用帶寬。這可能是管道,但它也可能在WCF堆棧中......處理異常代價昂貴,並且您正在儘可能嚴格的循環中執行其中的5000個異常。從異常更改爲WriteLine(),返回任何內容都不會修復問題,因爲它顯着降低了所需的帶寬/處理。 (我確實看到你提到過OneWay,但我認爲它沒有太大的改變,即使沒有返回異常,它仍然需要處理)。

嘗試將InstanceContextMode更改爲PerCall。這是「高容量」服務的標準設置。這將緩解的一些的擁堵。

此外爲了解決評論,託管這樣的服務是好的。 ServiceHost將管理自己的線程。

+0

什麼帶寬?在少數幾次呼叫後(這裏爲20),它失敗了。管道I/O重疊。這裏特別超出了什麼? – 2012-08-13 23:21:28

+0

什麼被超過是一個真正的節流問題,答案是:這取決於。看看我在這個問題中調整和性能測試的服務。它談到了我發現的一系列限制。請注意性能如何隨服務(或不)將其工作移至工作線程而發生變化。 http://stackoverflow.com/questions/7710220/wcf-performance-latency-and-scalability/7745600#7745600 – ErnieL 2012-08-14 01:59:06