2009-08-12 68 views
4

我剛剛花了4個小時(在英國凌晨3點)嘗試調試ASP.NET應用程序,該應用程序在由Framework(即,不是我的主題)管理的線程中導致異常。我剛剛發現,靜態方法ChannelFactory.CreateChannel的結果可以轉換爲IClientChannel並顯式地Disposed。我的意思是這一切都很好,但爲什麼:IClientChannel反模式

1)ChannelFactory.CreateChannel不會返回IClientChannel作爲out參數嗎?

2).Net的CreateChannel文檔沒有提到它?

3).Net文檔在示例中沒有顯示正確的使用模式(沒有配置代碼)?

不要誤解我的意思 - 我喜歡.Net框架。微軟(和Krzysztof Cwalina:參見設計框架指南)做了一件非常棒的工作。這就是爲什麼我沒有期待這樣的災難。我的意思是我該怎麼知道我的IMyService變量也支持IClientChannel,我應該明確地處理它?

這是一個ASP.NET日誌,如果有人感興趣。

Event Type: Error 
Event Source: ASP.NET 2.0.50727.0 
Event Category: None 
Event ID: 1334 
Date:  12/08/2009 
Time:  01:55:47 
User:  N/A 
Computer: WLGH3GIS 
Description: 
An unhandled exception occurred and the process was terminated. 

Application ID: /LM/W3SVC/1/Root/Maps 

Process ID: 3044 

Exception: System.NullReferenceException 

Message: Object reference not set to an instance of an object. 

StackTrace: at System.Threading.Overlapped.Free(NativeOverlapped* nativeOverlappedPtr) 
    at System.ServiceModel.Channels.OverlappedContext.Free() 
    at System.ServiceModel.Channels.PipeConnection.CloseHandle(Boolean abort, String timeoutErrorString, TransferOperation transferOperation) 
    at System.ServiceModel.Channels.PipeConnection.Close(TimeSpan timeout) 
    at System.ServiceModel.Channels.BufferedConnection.Close(TimeSpan timeout) 
    at System.ServiceModel.Channels.ConnectionPool.CloseItem(IConnection item, TimeSpan timeout) 
    at System.ServiceModel.Channels.CommunicationPool`2.EndpointConnectionPool.CloseItem(TItem item, TimeSpan timeout) 
    at System.ServiceModel.Channels.IdlingCommunicationPool`2.IdleTimeoutEndpointConnectionPool.CloseItem(TItem item, TimeSpan timeout) 
    at System.ServiceModel.Channels.CommunicationPool`2.EndpointConnectionPool.CloseIdleConnection(TItem connection, TimeSpan timeout) 
    at System.ServiceModel.Channels.IdlingCommunicationPool`2.IdleTimeoutEndpointConnectionPool.IdleTimeoutIdleConnectionPool.OnIdle() 
    at System.ServiceModel.Channels.IdlingCommunicationPool`2.IdleTimeoutEndpointConnectionPool.IdleTimeoutIdleConnectionPool.OnIdle(Object state) 
    at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2() 
    at System.Security.SecurityContext.Run(SecurityContext securityContext, ContextCallback callback, Object state) 
    at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke() 
    at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks() 
    at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state) 
    at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) 
    at System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) 
    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) 
+0

卡羅爾,你應該閱讀常見問題,然後將其作爲一個問題(也許也發佈一個答案)重新說。 – 2009-08-12 09:23:26

回答

4

卡羅爾,我知道這有點舊,但我想說聲謝謝。你的文章真的幫了我。

我的症狀是,當我試圖關閉服務器上的ChannelFactory時,無論我爲OpenTimeout,ReceiveTimeout,SendTimeout,InactivityTimeout或CloseTimeout設置的時間長度如何,它總會給出超時。

解決方案實際上是在客戶端上,將由ChannelFactory.CreateChannel返回的IMyServiceInterface轉換爲ICommunicationObject。然後,它可以很好地傳遞給Util.SafeCloseAndDispose(ICommunicationObject)方法,您可以看到複製並粘貼到網絡上。

當我在我的客戶端上做了這些之後,那麼服務器的ChannelFactory可以在一兩秒內關閉,而不會超時。

據我所知,來自Karol的文章的這種見解是網上這個問題拼寫出來的唯一地方之一。

再次感謝卡羅爾! :)

+0

非常歡迎。我想發佈一個人的發現總是好的。你永遠不知道別人什麼時候會谷歌。 – 2010-09-28 13:17:50