I am trying to get a better understanding of some of the inner workings of WCF. I have done a fair amount of looking around, but I have not been able to find a clear explanation of what ChannelFactory.Open()
does compared to IClientChannel.Open()
. What is the purpose of opening the factory? If the channel is being used for communication, what part does the factory play in the process after the channel has been created and opened?
The question was asked here, among other questions, but never answered directly.
EDIT:
After de-compiling the source code, I found some of the specific reasons why Open needs to be called on ChannelFactory, which is documented below.
What I'm still having trouble understanding is why this work is being done through mechanisms provided by the ICommunicationObject, when the factory isn't actually communicating with anything (as far as I know). Why not just handle these things when the object is constructed or disposed of?
I think I'm probably far enough in the weeds that such an answer may not be publicly available. Thank you to those who weighed in on the original question.
Open needs to be called in the factory, since it's an ICommunicationObject - before you use one of those, it needs to be opened. But in most cases the factory is opened automatically for you when you call things such as CreateChannel, for example, so you seldom need to worry about explicitly opening the factory.
Regarding Close, it really depends on which binding the factory is using. In most cases you're correct, the resource is mostly associated with the channel. But it's possible that a certain binding would multiplex multiple channels in the same underlying connection, so closing the channel would simply remove the channel from the list to be multiplexed. Only when the factory is closed is that the underlying connection is actually released.
After de-compiling a bunch of the related classes in System.ServiceModel
, I was able to get a little more information.
The Open
call appears to make its way down the inheritance tree to the CommunicationObject, where its Open
method is called. All this seems to do is provide a bunch of diagnostic information and raise a number of events.
The ChannelFactory
class uses the Open events do a number of things, including creating its inner channel factory:
protected override void OnOpening()
{
base.OnOpening();
this.innerFactory = this.CreateFactory();
if (this.innerFactory == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("InnerChannelFactoryWasNotSet")));
}
}
As has been mentioned by others here, the Close events are also used to do things like close all of the underlying channels, (by way of it's internal channel factory):
protected override void OnClose(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
while (true)
{
IChannel channel;
lock (base.ThisLock)
{
if (this.channelsList.Count == 0)
{
break;
}
channel = this.channelsList[0];
}
channel.Close(timeoutHelper.RemainingTime());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With