2009-08-12 67 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