internal PooledChannel(ChannelManager owner, ChannelFactoryReference factoryReference, EndpointAddress factoryKey, IChannel channel)
 {
     this.owner            = owner;
     this.factoryReference = factoryReference;
     this.factoryKey       = factoryKey;
     this.channel          = channel;
 }
        void ReturnChannelFactory(EndpointAddress key, ChannelFactoryReference channelFactory)
        {
            if (channelFactory == null)
            {
                return;
            }

            lock (this.ThisLock)
            {
                bool closeFactory   = channelFactory.Release();
                bool invalidFactory = (channelFactory.ChannelFactory.State != CommunicationState.Opened);

                if (closeFactory || invalidFactory)
                {
                    ChannelFactoryReference currentFactory = null;
                    this.factoryCache.TryGetValue(key, out currentFactory);

                    if (currentFactory == channelFactory)
                    {
                        this.factoryCache.Remove(key);
                    }

                    if (closeFactory)
                    {
                        channelFactory.Close(ServiceDefaults.CloseTimeout);
                    }
                }
            }
        }
        public PooledChannel TakeChannel(EndpointAddress address, Uri via, out ChannelPoolKey key)
        {
            PooledChannel channel = null;

            key = null;

            if (!this.closed)
            {
                ChannelFactoryReference factory = this.TakeChannelFactory(address);
                if (factory != null)
                {
                    bool channelCreated = false;
                    try
                    {
                        EndpointAddress cacheAddress = address;
                        if (factory.SupportsClientAuthentication)
                        {
                            cacheAddress = ChannelManagerHelpers.BuildCacheAddressWithIdentity(address);
                        }

                        channel = this.channelPool.TakeConnection(cacheAddress, via, ServiceDefaults.OpenTimeout, out key);
                        while (channel != null && channel.State != CommunicationState.Opened)
                        {
                            // Loop will exit because non-opened channels are returned with 'connectionStillGood=false'
                            this.channelPool.ReturnConnection(key, channel, false, ServiceDefaults.CloseTimeout);
                            channel = this.channelPool.TakeConnection(cacheAddress, via, ServiceDefaults.OpenTimeout, out key);
                        }

                        if (channel == null)
                        {
                            channel = this.CreateChannel(factory, address, via, out channelCreated);
                        }
                    }
                    finally
                    {
                        if (!channelCreated)
                        {
                            this.ReturnChannelFactory(address, factory);
                        }
                    }
                }
            }

            return(channel);
        }
        PooledChannel CreateChannel(ChannelFactoryReference factory, EndpointAddress address, Uri via, out bool channelCreated)
        {
            PooledChannel pooledChannel = null;

            channelCreated = false;

            IChannel channel = ChannelManagerHelpers.CreateChannel(factory.ContractType, factory.ChannelFactory, (via == defaultViaUri) ? null : via.ToString());

            if (channel != null)
            {
                pooledChannel = new PooledChannel(this, factory, address, channel);
                lock (this.ThisLock)
                {
                    this.newChannels.Add(pooledChannel);
                }

                channelCreated = true;
            }

            return(pooledChannel);
        }