Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ChannelFactory.Open VS IClientChannel.Open

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.

like image 751
Trey Combs Avatar asked Aug 16 '12 03:08

Trey Combs


2 Answers

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.

like image 174
Cybermaxs Avatar answered Oct 16 '22 09:10

Cybermaxs


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());
    }
}
like image 28
Trey Combs Avatar answered Oct 16 '22 09:10

Trey Combs