I just spent 4 hours (this is 3 hours in the UK) trying to debug an ASP.NET application that threw an exception in a thread controlled by the Framework (i.e. not my thread). I just found out that the result of the static ChannelFactory.CreateChannel method can be transferred to IClientChannel and explicitly deleted. I mean, everything is beautiful and pleasant, but why:
1) ChannelFactory.CreateChannel does not return IClientChannel as an output parameter?
2). Does the NetNet documentation for CreateChannel not mention this?
3). Net documentation not showing proper usage model in examples (without dispose code)?
Don't get me wrong - I love the .Net framework. Microsoft (and Krzysztof Cwalina: see Framework Development Guide) did a great job. That is why I did not expect such a catastrophe. I mean, how the hell should I know that my IMyService variable also supports IClientChannel, and I have to explicitly manage it?
Here is the ASP.NET magazine if anyone is interested.
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)
source share