ConnectionOrientedTransportChannelFactory.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / ConnectionOrientedTransportChannelFactory.cs / 1 / ConnectionOrientedTransportChannelFactory.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.ServiceModel.Channels 
{
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 
    using System.Diagnostics;
    using System.IO; 
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using System.Text; 
    using System.Threading;
    using System.ServiceModel.Diagnostics; 
 
    abstract class ConnectionOrientedTransportChannelFactory : TransportChannelFactory
        , IConnectionOrientedTransportChannelFactorySettings 
    {
        int connectionBufferSize;
        IConnectionInitiator connectionInitiator;
        ConnectionPool connectionPool; 
        string connectionPoolGroupName;
        bool exposeConnectionProperty; 
        TimeSpan idleTimeout; 
        int maxBufferSize;
        int maxOutboundConnectionsPerEndpoint; 
        TimeSpan maxOutputDelay;
        TransferMode transferMode;
        ISecurityCapabilities securityCapabilities;
        StreamUpgradeProvider upgrade; 

        internal ConnectionOrientedTransportChannelFactory( 
            ConnectionOrientedTransportBindingElement bindingElement, BindingContext context, 
            string connectionPoolGroupName, TimeSpan idleTimeout, int maxOutboundConnectionsPerEndpoint)
            : base(bindingElement, context) 
        {
            if (bindingElement.TransferMode == TransferMode.Buffered && bindingElement.MaxReceivedMessageSize > int.MaxValue)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new ArgumentOutOfRangeException("bindingElement.MaxReceivedMessageSize",
                    SR.GetString(SR.MaxReceivedMessageSizeMustBeInIntegerRange))); 
            } 

            this.connectionBufferSize = bindingElement.ConnectionBufferSize; 
            this.connectionPoolGroupName = connectionPoolGroupName;
            this.exposeConnectionProperty = bindingElement.ExposeConnectionProperty;
            this.idleTimeout = idleTimeout;
            this.maxBufferSize = bindingElement.MaxBufferSize; 
            this.maxOutboundConnectionsPerEndpoint = maxOutboundConnectionsPerEndpoint;
            this.maxOutputDelay = bindingElement.MaxOutputDelay; 
            this.transferMode = bindingElement.TransferMode; 

            Collection upgradeBindingElements = 
                context.BindingParameters.FindAll();

            if (upgradeBindingElements.Count > 1)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MultipleStreamUpgradeProvidersInParameters)));
            } 
            else if ((upgradeBindingElements.Count == 1) && this.SupportsUpgrade(upgradeBindingElements[0])) 
            {
                this.upgrade = upgradeBindingElements[0].BuildClientStreamUpgradeProvider(context); 
                context.BindingParameters.Remove();
                this.securityCapabilities = upgradeBindingElements[0].GetProperty(context);
            }
        } 

        public int ConnectionBufferSize 
        { 
            get
            { 
                return this.connectionBufferSize;
            }
        }
 
        internal IConnectionInitiator ConnectionInitiator
        { 
            get 
            {
                if (this.connectionInitiator == null) 
                {
                    lock (ThisLock)
                    {
                        if (this.connectionInitiator == null) 
                        {
                            this.connectionInitiator = GetConnectionInitiator(); 
                            if (DiagnosticUtility.ShouldUseActivity) 
                            {
                                this.connectionInitiator = new TracingConnectionInitiator(this.connectionInitiator, 
                                    ServiceModelActivity.Current != null && ServiceModelActivity.Current.ActivityType == ActivityType.OpenClient);
                            }
                        }
                    } 
                }
 
                return this.connectionInitiator; 
            }
        } 

        public string ConnectionPoolGroupName
        {
            get 
            {
                return connectionPoolGroupName; 
            } 
        }
 
        public TimeSpan IdleTimeout
        {
            get
            { 
                return this.idleTimeout;
            } 
        } 

        public int MaxBufferSize 
        {
            get
            {
                return maxBufferSize; 
            }
        } 
 
        public int MaxOutboundConnectionsPerEndpoint
        { 
            get
            {
                return maxOutboundConnectionsPerEndpoint;
            } 
        }
 
        public TimeSpan MaxOutputDelay 
        {
            get 
            {
                return maxOutputDelay;
            }
        } 

        public StreamUpgradeProvider Upgrade 
        { 
            get
            { 
                StreamUpgradeProvider localUpgrade = this.upgrade;
                ThrowIfDisposed();
                return localUpgrade;
            } 
        }
 
        public TransferMode TransferMode 
        {
            get 
            {
                return transferMode;
            }
        } 

        int IConnectionOrientedTransportFactorySettings.MaxBufferSize 
        { 
            get { return MaxBufferSize; }
        } 

        TransferMode IConnectionOrientedTransportFactorySettings.TransferMode
        {
            get { return TransferMode; } 
        }
 
        StreamUpgradeProvider IConnectionOrientedTransportFactorySettings.Upgrade 
        {
            get { return Upgrade; } 
        }

        ServiceSecurityAuditBehavior IConnectionOrientedTransportFactorySettings.AuditBehavior
        { 
            #pragma warning suppress 56503 // Internal method.
            get { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityAuditNotSupportedOnChannelFactory))); } 
        } 

        public override T GetProperty() 
        {
            if (typeof(T) == typeof(ISecurityCapabilities))
            {
                return (T)(object)this.securityCapabilities; 
            }
 
            return base.GetProperty(); 
        }
 
        internal abstract IConnectionInitiator GetConnectionInitiator();

        internal abstract ConnectionPool GetConnectionPool();
 
        internal abstract void ReleaseConnectionPool(ConnectionPool pool, TimeSpan timeout);
 
        protected override TChannel OnCreateChannel(EndpointAddress address, Uri via) 
        {
            base.ValidateScheme(via); 

            if (TransferMode == TransferMode.Buffered)
            {
                // typeof(TChannel) == typeof(IDuplexSessionChannel) 
                return (TChannel)(object)new ClientFramingDuplexSessionChannel(this, this, address, via,
                    ConnectionInitiator, connectionPool, exposeConnectionProperty); 
            } 

            // typeof(TChannel) == typeof(IRequestChannel) 
            return (TChannel)(object)new StreamedFramingRequestChannel(this, this, address, via,
                ConnectionInitiator, connectionPool);
        }
 
        bool GetUpgradeAndConnectionPool(out StreamUpgradeProvider upgradeCopy, out ConnectionPool poolCopy)
        { 
            if (this.upgrade != null || this.connectionPool != null) 
            {
                lock (ThisLock) 
                {
                    if (this.upgrade != null || this.connectionPool != null)
                    {
                        upgradeCopy = this.upgrade; 
                        poolCopy = this.connectionPool;
                        this.upgrade = null; 
                        this.connectionPool = null; 
                        return true;
                    } 
                }
            }

            upgradeCopy = null; 
            poolCopy = null;
            return false; 
        } 

        protected override void OnAbort() 
        {
            StreamUpgradeProvider localUpgrade;
            ConnectionPool localConnectionPool;
            if (GetUpgradeAndConnectionPool(out localUpgrade, out localConnectionPool)) 
            {
                if (localConnectionPool != null) 
                { 
                    ReleaseConnectionPool(localConnectionPool, TimeSpan.Zero);
                } 

                if (localUpgrade != null)
                {
                    localUpgrade.Abort(); 
                }
            } 
        } 

        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 
        {
            return new CloseAsyncResult(this, timeout, callback, state);
        }
 
        protected override void OnEndClose(IAsyncResult result)
        { 
            CloseAsyncResult.End(result); 
        }
 
        protected override void OnClose(TimeSpan timeout)
        {
            StreamUpgradeProvider localUpgrade;
            ConnectionPool localConnectionPool; 

            if (GetUpgradeAndConnectionPool(out localUpgrade, out localConnectionPool)) 
            { 
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
 
                if (localConnectionPool != null)
                {
                    ReleaseConnectionPool(localConnectionPool, timeoutHelper.RemainingTime());
                } 

                if (localUpgrade != null) 
                { 
                    localUpgrade.Close(timeoutHelper.RemainingTime());
                } 
            }
        }

        protected override void OnOpening() 
        {
            base.OnOpening(); 
            this.connectionPool = GetConnectionPool(); // returns an already opened pool 
            DiagnosticUtility.DebugAssert(this.connectionPool != null, "ConnectionPool should always be found");
        } 

        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new OpenAsyncResult(this.Upgrade, timeout, callback, state); 
        }
 
        protected override void OnEndOpen(IAsyncResult result) 
        {
            OpenAsyncResult.End(result); 
        }

        class OpenAsyncResult : AsyncResult
        { 
            ICommunicationObject communicationObject;
            static AsyncCallback onOpenComplete = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnOpenComplete)); 
 
            public OpenAsyncResult(ICommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state) 
            {
                this.communicationObject = communicationObject;

                if (this.communicationObject == null) 
                {
                    this.Complete(true); 
                    return; 
                }
 
                IAsyncResult result = this.communicationObject.BeginOpen(timeout, onOpenComplete, this);
                if (result.CompletedSynchronously)
                {
                    this.communicationObject.EndOpen(result); 
                    this.Complete(true);
                } 
            } 

            static void OnOpenComplete(IAsyncResult result) 
            {
                if (result.CompletedSynchronously)
                    return;
 
                OpenAsyncResult thisPtr = (OpenAsyncResult)result.AsyncState;
                Exception exception = null; 
 
                try
                { 
                    thisPtr.communicationObject.EndOpen(result);
                }
                catch (Exception e)
                { 
                    if (DiagnosticUtility.IsFatal(e))
                        throw; 
 
                    exception = e;
                } 

                thisPtr.Complete(false, exception);
            }
 
            public static void End(IAsyncResult result)
            { 
                AsyncResult.End(result); 
            }
        } 

        protected override void OnOpen(TimeSpan timeout)
        {
            StreamUpgradeProvider localUpgrade = this.Upgrade; 
            if (localUpgrade != null)
            { 
                localUpgrade.Open(timeout); 
            }
        } 

        protected virtual bool SupportsUpgrade(StreamUpgradeBindingElement upgradeBindingElement)
        {
            return true; 
        }
 
        class CloseAsyncResult : AsyncResult 
        {
            ConnectionOrientedTransportChannelFactory parent; 
            ConnectionPool connectionPool;
            StreamUpgradeProvider upgradeProvider;
            TimeoutHelper timeoutHelper;
            static AsyncCallback onCloseComplete = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnCloseComplete)); 
            static WaitCallback onReleaseConnectionPoolScheduled;
 
            public CloseAsyncResult(ConnectionOrientedTransportChannelFactory parent, TimeSpan timeout, 
                AsyncCallback callback, object state)
                : base(callback, state) 
            {
                this.parent = parent;
                this.timeoutHelper = new TimeoutHelper(timeout);
 
                this.parent.GetUpgradeAndConnectionPool(out this.upgradeProvider, out this.connectionPool);
 
                if (this.connectionPool == null) 
                {
                    if (this.HandleReleaseConnectionPoolComplete()) 
                    {
                        this.Complete(true);
                    }
                } 
                else
                { 
                    if (onReleaseConnectionPoolScheduled == null) 
                    {
                        onReleaseConnectionPoolScheduled = new WaitCallback(OnReleaseConnectionPoolScheduled); 
                    }
                    IOThreadScheduler.ScheduleCallback(onReleaseConnectionPoolScheduled, this);
                }
            } 

            bool HandleReleaseConnectionPoolComplete() 
            { 
                if (this.upgradeProvider == null)
                { 
                    return true;
                }
                else
                { 
                    IAsyncResult result = this.upgradeProvider.BeginClose(this.timeoutHelper.RemainingTime(),
                        onCloseComplete, this); 
 
                    if (result.CompletedSynchronously)
                    { 
                        this.upgradeProvider.EndClose(result);
                        return true;
                    }
                } 
                return false;
            } 
 
            bool OnReleaseConnectionPoolScheduled()
            { 
                this.parent.ReleaseConnectionPool(this.connectionPool, this.timeoutHelper.RemainingTime());
                return this.HandleReleaseConnectionPoolComplete();
            }
 
            static void OnReleaseConnectionPoolScheduled(object state)
            { 
                CloseAsyncResult thisPtr = (CloseAsyncResult)state; 
                bool completeSelf;
                Exception completionException = null; 
                try
                {
                    completeSelf = thisPtr.OnReleaseConnectionPoolScheduled();
                } 
                catch (Exception e)
                { 
                    if (DiagnosticUtility.IsFatal(e)) 
                    {
                        throw; 
                    }

                    completeSelf = true;
                    completionException = e; 
                }
 
                if (completeSelf) 
                {
                    thisPtr.Complete(false, completionException); 
                }
            }

            static void OnCloseComplete(IAsyncResult result) 
            {
                if (result.CompletedSynchronously) 
                    return; 

                CloseAsyncResult thisPtr = (CloseAsyncResult)result.AsyncState; 
                Exception exception = null;

                try
                { 
                    thisPtr.upgradeProvider.EndClose(result);
                } 
                catch (Exception e) 
                {
                    if (DiagnosticUtility.IsFatal(e)) 
                        throw;

                    exception = e;
                } 

                thisPtr.Complete(false, exception); 
            } 

            public static void End(IAsyncResult result) 
            {
                AsyncResult.End(result);
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK