2016-08-03 462 views
0

我知道這裏有100萬個帖子,但我不明白這個。 我有一個極值簡單的例子管道服務:Mysterious =>從管道讀取時發生錯誤:管道已結束。 (109,0x6d)

​​

當我把它的人,一切都很好,但是當兩個客戶端同時調用它會拋出該異常。 服務器直接設置一個新線程並返回給客戶端。

public void RiskExport(long sraid, long revID, string JobID) 
{ 
ThreadStarter starter = new ThreadStarter(new ThreadStartWithParameter(RunExportJob), new SRAInfo() { sraid = sraid, revID = revID, JobID = JobID }); 
Thread t = new Thread(new System.Threading.ThreadStart(starter.ThreadStartEntry)); 
t.IsBackground = true; 
t.Start(); 
} 

因此,它不能是一個超時的問題,因爲它從cleint到服務器和後面需要1秒的時間。尤其是當我在同步稱它爲環路從我的單元測試

string JobID = ""; 
for (int i = 0; i < 100; i++) 
{ 
string baseAddress = "net.pipe://localhost/SRADocumentService"; 
ChannelFactory<ISRARiskExport> factory = new ChannelFactory<ISRARiskExport>(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress(baseAddress)); 
ISRARiskExport svc = factory.CreateChannel(); 
JobID = Guid.NewGuid().ToString(); 
svc.RiskExport(sraid, revID, JobID); 
} 

我都準備好激活WCF跟蹤。在這裏我可以看到每次調用拋出異常。詳細信息窗格根本沒有幫助我,因爲它向我顯示兩次異常=> 從管道讀取時發生錯誤:管道已結束。 (109,0x6d)。

enter image description here

隨着不同的堆棧跟蹤=>

enter image description here

enter image description here

我也看到在DebugView中的例外來長後撥回是在客戶端。 我的問題是:

  1. 爲什麼服務工作,因爲即使當它拋出這個異常

  2. 我怎樣才能擺脫例外的,因爲他們都得到日誌文件和我expectet我不會感冒。

THX邁克爾

+0

沒有這個例子,沒有人可以幫助你。您可能想編輯帖子。 –

+0

哈哈 - 我無法添加所有的內容。所以我做了一些步驟。 –

回答

0

我們已經看到了這樣的行爲是由於如何命名管道池在WCF內部實現。在我們的例子中,這些例外或多或少是隨機的(不是每次調用之後),但是在研究MS參考資源後,我們認爲它們是不可避免的。你提到「在客戶回來之後很久就會發生例外情況」,這讓我認爲你正在觀察同樣的行爲。

您可以看到hereNamedPipeConnectionPoolSettings的「證明」:IdleTimeout設置爲某個默認值,即等於2 minutes

也許我們錯了我們的決定,這是不可避免的,因爲我現在看到NamedPipeConnectionPoolSettings類是公共和IdleTimeout屬性也是公共的,可以被設置爲TimeSpan.MaxValue應防止管道和這些異常關閉。

希望這會有所幫助。

0

我得到這個相同的序列異常與非常相似的跟蹤數據,並且在將綁定更改爲以下異常停止後。請注意,我不知道這些更改的含義是什麼,請謹慎使用。

public Binding GetBinding() 
    { 
     var binding = new NetNamedPipeBinding 
     { 
      OpenTimeout = TimeSpan.FromMinutes(15), 
      SendTimeout = TimeSpan.FromMinutes(15), 
      CloseTimeout = TimeSpan.FromMinutes(15), 
      MaxConnections = 200, 
      MaxBufferSize = int.MaxValue, 
      MaxReceivedMessageSize = int.MaxValue, 
      MaxBufferPoolSize = int.MaxValue, 
      TransactionFlow = false, 
      TransactionProtocol = TransactionProtocol.WSAtomicTransaction11, 
      TransferMode = TransferMode.StreamedRequest, 
      HostNameComparisonMode = HostNameComparisonMode.WeakWildcard 
     }; 
     binding.Security.Transport.ProtectionLevel = ProtectionLevel.None; 
     return binding; 
    }