IClientChannel反模式

时间:2009-08-12 02:21:41

标签: c# .net asp.net wcf

我只花了4个小时(在英国凌晨3点)尝试调试ASP.NET应用程序,这在Framework管理的线程中引起了异常(即不是我的线程)。我刚刚发现静态方法ChannelFactory.CreateChannel的结果可以转换为IClientChannel并显式Disposed。我的意思是一切都很好,但为什么:

1)ChannelFactory.CreateChannel不会将IClientChannel作为out参数返回?

2)。CreateChannel的.Net文档没有提到它?

3).Net文档没有在示例中显示正确的使用模式(没有配置代码)?

别误会我的意思 - 我喜欢.Net框架。微软(和Krzysztof Cwalina:参见设计框架指南)做得非常好。这就是为什么我没想到会发生这样的灾难。我的意思是我应该怎么知道我的IMyService变量也支持IClientChannel,我应该明确地处理它?<​​/ p>

如果有人感兴趣,这是一个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)

1 个答案:

答案 0 :(得分:4)

卡罗尔,我知道这有点老了,但我想说谢谢。你的帖子真的帮助了我。

我遇到的症状是,当我尝试关闭服务器上的ChannelFactory时,无论我为OpenTimeout,ReceiveTimeout,SendTimeout,InactivityTimeout还是CloseTimeout设置的时间长度,它总是会给出超时。

解决方案实际上是在客户端上,将ChannelFactory.CreateChannel返回的IMyServiceInterface转换为ICommunicationObject。然后,它可以很好地传递给您在整个Web上复制和粘贴的Util.SafeCloseAndDispose(ICommunicationObject)方法。

在我的客户端上执行此操作后,服务器的ChannelFactory可以在一两秒钟内关闭,不会再超时。

据我所知,来自Karol帖子的这一见解是网上解决此问题的唯一地方之一。

再次感谢,卡罗尔! :)