很長的時間之間的響應,但我認爲別人也可能會遇到這個問題,所以在這裏。
我建議在VS中連接到你的服務器,進入Debug菜單,選擇'exceptions',然後檢查'System.Net.Sockets.SocketException'異常。這會在發生任何套接字異常時破壞您的程序。
就我而言,我最近開始看到這個問題,經過大量的調試發現就在Lease Manager停止檢查租約之前,發生了一個SocketException。在我的情況,插座的例外是AddressChangedCallback
,與堆棧跟蹤:
1 [External Code]
2 System.dll!System.Net.Dns.TryGetAddrInfo(string name = "me.win.mycompany.com", System.Net.AddressInfoHints flags, out System.Net.IPHostEntry hostinfo = null)
3 System.dll!System.Net.Dns.GetAddrInfo(string name)
4 System.dll!System.Net.Dns.InternalGetHostByName(string hostName, bool includeIPv6)
5 System.dll!System.Net.Dns.GetHostEntry(string hostNameOrAddress)
6 System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.CoreChannel.UpdateCachedIPAddresses()
7 System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.CoreChannel.OnNetworkAddressChanged(object sender = null, System.EventArgs e = {System.EventArgs})
8 mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
9 mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
10 mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
11 System.dll!System.Net.NetworkInformation.NetworkChange.AddressChangeListener.AddressChangedCallback(object stateObject, bool signaled)
12 mscorlib.dll!System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(object state, bool timedOut)
13 [External Code]
這AddressChangedCallback,
其中,於我而言,似乎與一個網絡適配器下降或正在改變(你可以看到你的網絡適配器通過持有windows+r
然後輸入ncpa.cpl
- 如果您有兩個或更多可能的事件是由您在它們之間切換引起的)似乎會導致套接字停止讀取。這意味着下次LeaseManager使用遠程連接來檢查遠程租約時,它無法從死鎖套接字讀取租約。所以,它做了合理的事情 - 斷開贊助商,因爲我們不能再閱讀它,並將其從贊助商名單中刪除。而且由於它可能是所討論對象的唯一讚助商,因此該對象得不到LeaseManger的贊助,讓它免費供GC最終接受。
解決此問題的一種方法是,在您的InitializeLifetimeService()
方法中,返回null而不是設置超時。這繞過了LeaseManager,因此您不必擔心因爲套接字異常而被取消贊助的對象,因爲您首先不使用租約。但是,如果您像我一樣,這也意味着您可以在服務器上在一段時間內建立對象和非託管資源的堆積。圍繞我看到的構建問題的唯一方法是讓您的遠程對象實現Dispose
,並確保您在完成時處置它。基本上,你不能依賴LeaseManager處理垃圾收集,所以你必須自己做GC,這是一種老式的方式。
另外值得注意組成:ITrackingHandler對象將允許您跟蹤時LeaseManager相關的對象斷開,編組和取消封送。這對於弄清楚發生了什麼是一個很大的幫助,因爲我可以看到一個對象正在斷開連接,而不是從電話停止發生的事實中推斷出來。