ChannelDispatcher.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 / Dispatcher / ChannelDispatcher.cs / 1 / ChannelDispatcher.cs

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

namespace System.ServiceModel.Dispatcher 
{
    using System; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Diagnostics; 
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher;
    using System.ServiceModel.Diagnostics;
    using System.Transactions; 
    using System.Text;
    using System.Globalization; 
 
    public class ChannelDispatcher : ChannelDispatcherBase
    { 
        ThreadSafeMessageFilterTable addressTable;
        string bindingName;
        SynchronizedCollection channelInitializers;
        CommunicationObjectManager channels; 
        EndpointDispatcherCollection endpointDispatchers;
        Collection errorHandlers; 
        EndpointDispatcherTable filterTable; 
        ServiceHostBase host;
        bool isTransactedReceive; 
        readonly IChannelListener listener;
        ListenerHandler listenerHandler;
        int maxTransactedBatchSize;
        MessageVersion messageVersion; 
        SynchronizedChannelCollection pendingChannels; // app has not yet seen these.
        bool receiveSynchronously; 
        bool includeExceptionDetailInFaults; 
        ServiceThrottle serviceThrottle;
        bool session; 
        SharedRuntimeState shared;
        IDefaultCommunicationTimeouts timeouts;
        IsolationLevel transactionIsolationLevel = ServiceBehaviorAttribute.DefaultIsolationLevel;
        bool transactionIsolationLevelSet; 
        TimeSpan transactionTimeout;
 
        ErrorBehavior errorBehavior; 

        internal ChannelDispatcher(SharedRuntimeState shared) 
        {
            this.Initialize(shared);
        }
 
        public ChannelDispatcher(IChannelListener listener)
            : this(listener, null, null) 
        { 
        }
 
        public ChannelDispatcher(IChannelListener listener, string bindingName)
            : this(listener, bindingName, null)
        {
        } 

        public ChannelDispatcher(IChannelListener listener, string bindingName, IDefaultCommunicationTimeouts timeouts) 
        { 
            if (listener == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("listener");
            }

            this.listener = listener; 
            this.bindingName = bindingName;
            this.timeouts = new ImmutableCommunicationTimeouts(timeouts); 
 
            this.session = ((listener is IChannelListener) ||
                            (listener is IChannelListener) || 
                            (listener is IChannelListener));

            this.Initialize(new SharedRuntimeState(true));
        } 

        void Initialize(SharedRuntimeState shared) 
        { 
            this.shared = shared;
            this.endpointDispatchers = new EndpointDispatcherCollection(this); 
            this.channelInitializers = this.NewBehaviorCollection();
            this.channels = new CommunicationObjectManager(this.ThisLock);
            this.pendingChannels = new SynchronizedChannelCollection(this.ThisLock);
            this.errorHandlers = new Collection(); 
            this.isTransactedReceive = false;
            this.receiveSynchronously = false; 
            this.serviceThrottle = null; 
            this.transactionTimeout = TimeSpan.Zero;
 
            if (this.listener != null)
            {
                this.listener.Faulted += new EventHandler(OnListenerFaulted);
            } 
        }
 
        public string BindingName 
        {
            get { return this.bindingName; } 
        }

        public SynchronizedCollection ChannelInitializers
        { 
            get { return this.channelInitializers; }
        } 
 
        protected override TimeSpan DefaultCloseTimeout
        { 
            get
            {
                if (this.timeouts != null)
                { 
                    return this.timeouts.CloseTimeout;
                } 
                else 
                {
                    return ServiceDefaults.CloseTimeout; 
                }
            }
        }
 
        protected override TimeSpan DefaultOpenTimeout
        { 
            get 
            {
                if (this.timeouts != null) 
                {
                    return this.timeouts.OpenTimeout;
                }
                else 
                {
                    return ServiceDefaults.OpenTimeout; 
                } 
            }
        } 

        internal EndpointDispatcherTable EndpointDispatcherTable
        {
            get { return this.filterTable; } 
        }
 
        internal CommunicationObjectManager Channels 
        {
            get { return this.channels; } 
        }

        public SynchronizedCollection Endpoints
        { 
            get { return this.endpointDispatchers; }
        } 
 
        public Collection ErrorHandlers
        { 
            get { return this.errorHandlers; }
        }

        public MessageVersion MessageVersion 
        {
            get { return this.messageVersion; } 
            set 
            {
                this.messageVersion = value; 
                this.ThrowIfDisposedOrImmutable();
            }
        }
 
        internal bool Session
        { 
            get { return this.session; } 
        }
 
        public override ServiceHostBase Host
        {
            get { return this.host; }
        } 

        internal bool EnableFaults 
        { 
            get { return this.shared.EnableFaults; }
            set 
            {
                this.ThrowIfDisposedOrImmutable();
                this.shared.EnableFaults = value;
            } 
        }
 
        internal bool IsOnServer 
        {
            get { return this.shared.IsOnServer; } 
        }

        public bool IsTransactedAccept
        { 
            get { return this.isTransactedReceive && this.session; }
        } 
 
        public bool IsTransactedReceive
        { 
            get
            {
                return this.isTransactedReceive;
            } 
            set
            { 
                this.ThrowIfDisposedOrImmutable(); 
                this.isTransactedReceive = value;
            } 
        }

        public override IChannelListener Listener
        { 
            get { return this.listener; }
        } 
 
        public int MaxTransactedBatchSize
        { 
            get
            {
                return this.maxTransactedBatchSize;
            } 
            set
            { 
                if (value < 0) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, 
                                                    SR.GetString(SR.ValueMustBeNonNegative)));
                }

                this.ThrowIfDisposedOrImmutable(); 
                this.maxTransactedBatchSize = value;
            } 
        } 

        public ServiceThrottle ServiceThrottle 
        {
            get
            {
                return this.serviceThrottle; 
            }
            set 
            { 
                this.ThrowIfDisposedOrImmutable();
                this.serviceThrottle = value; 
            }
        }

        public bool ManualAddressing 
        {
            get { return this.shared.ManualAddressing; } 
            set 
            {
                this.ThrowIfDisposedOrImmutable(); 
                this.shared.ManualAddressing = value;
            }
        }
 
        internal SynchronizedChannelCollection PendingChannels
        { 
            get { return this.pendingChannels; } 
        }
 
        public bool ReceiveSynchronously
        {
            get
            { 
                return this.receiveSynchronously;
            } 
            set 
            {
                this.ThrowIfDisposedOrImmutable(); 
                this.receiveSynchronously = value;
            }
        }
 
        public bool IncludeExceptionDetailInFaults
        { 
            get { return this.includeExceptionDetailInFaults; } 
            set
            { 
                lock (this.ThisLock)
                {
                    this.ThrowIfDisposedOrImmutable();
                    this.includeExceptionDetailInFaults = value; 
                }
            } 
        } 

        internal IDefaultCommunicationTimeouts DefaultCommunicationTimeouts 
        {
            get { return this.timeouts; }
        }
 
        public IsolationLevel TransactionIsolationLevel
        { 
            get { return this.transactionIsolationLevel; } 
            set
            { 
                switch (value)
                {
                    case IsolationLevel.Serializable:
                    case IsolationLevel.RepeatableRead: 
                    case IsolationLevel.ReadCommitted:
                    case IsolationLevel.ReadUncommitted: 
                    case IsolationLevel.Unspecified: 
                    case IsolationLevel.Chaos:
                    case IsolationLevel.Snapshot: 
                        break;

                    default:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value")); 
                }
 
                this.ThrowIfDisposedOrImmutable(); 
                this.transactionIsolationLevel = value;
                this.transactionIsolationLevelSet = true; 
            }
        }

        internal bool TransactionIsolationLevelSet 
        {
            get { return this.transactionIsolationLevelSet; } 
        } 

        public TimeSpan TransactionTimeout 
        {
            get
            {
                return this.transactionTimeout; 
            }
            set 
            { 
                if (value < TimeSpan.Zero)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value,
                        SR.GetString(SR.SFxTimeoutOutOfRange0)));
                }
 
                if (TimeoutHelper.IsTooLarge(value))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, 
                        SR.GetString(SR.SFxTimeoutOutOfRangeTooBig)));
                } 

                this.ThrowIfDisposedOrImmutable();
                this.transactionTimeout = value;
            } 
        }
 
        void AbortPendingChannels() 
        {
            lock (this.ThisLock) 
            {
                for (int i=this.pendingChannels.Count-1; i>=0; i--)
                {
                    this.pendingChannels[i].Abort(); 
                }
            } 
        } 

        public override void CloseInput() 
        {
            lock (this.ThisLock)
            {
                if (DiagnosticUtility.ShouldTraceInformation) 
                {
                    for (int i=0; i NewBehaviorCollection() 
        {
            return new ChannelDispatcherBehaviorCollection(this); 
        }

        void OnAddEndpoint(EndpointDispatcher endpoint)
        { 
            lock (this.ThisLock)
            { 
                endpoint.Attach(this); 

                if (this.State == CommunicationState.Opened) 
                {
                    if (this.addressTable != null)
                    {
                        this.addressTable.Add(endpoint.AddressFilter, endpoint.EndpointAddress, endpoint.FilterPriority); 
                    }
 
                    this.filterTable.AddEndpoint(endpoint); 
                }
            } 
        }

        void OnRemoveEndpoint(EndpointDispatcher endpoint)
        { 
            lock (this.ThisLock)
            { 
                if (this.State == CommunicationState.Opened) 
                {
                    this.filterTable.RemoveEndpoint(endpoint); 

                    if (this.addressTable != null)
                    {
                        this.addressTable.Remove(endpoint.AddressFilter); 
                    }
                } 
 
                endpoint.Detach(this);
            } 
        }

        protected override void OnAbort()
        { 
            if (this.listener != null)
            { 
                this.listener.Abort(); 
            }
 
            ListenerHandler handler = this.listenerHandler;
            if (handler != null)
            {
                handler.Abort(); 
            }
 
            this.AbortPendingChannels(); 
        }
 
        protected override void OnClose(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
 
            if (this.listener != null)
            { 
                this.listener.Close(timeoutHelper.RemainingTime()); 
            }
 
            ListenerHandler handler = this.listenerHandler;
            if (handler != null)
            {
                handler.Close(timeoutHelper.RemainingTime()); 
            }
 
            this.AbortPendingChannels(); 
        }
 
        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
        {
            List list = new List();
 
            if (this.listener != null)
            { 
                list.Add(this.listener); 
            }
 
            ListenerHandler handler = this.listenerHandler;
            if (handler != null)
            {
                list.Add(handler); 
            }
 
            return new CloseCollectionAsyncResult(timeout, callback, state, list); 
        }
 
        protected override void OnEndClose(IAsyncResult result)
        {
            try
            { 
                CloseCollectionAsyncResult.End(result);
            } 
            finally 
            {
                this.AbortPendingChannels(); 
            }
        }

        protected override void OnClosed() 
        {
            base.OnClosed(); 
 
            if (DiagnosticUtility.ShouldTraceInformation)
            { 
                for (int i=0; i namesSeen = new Collection();
            StringBuilder endpointContractNames = new StringBuilder(); 

            lock (this.ThisLock) 
            { 
                foreach (EndpointDispatcher ed in this.Endpoints)
                { 
                    if (!namesSeen.Contains(ed.ContractName))
                    {
                        if (endpointContractNames.Length > 0)
                        { 
                            endpointContractNames.Append(CultureInfo.CurrentCulture.TextInfo.ListSeparator);
                            endpointContractNames.Append(Space); 
                        } 

                        endpointContractNames.Append(OpenQuote); 
                        endpointContractNames.Append(ed.ContractName);
                        endpointContractNames.Append(CloseQuote);

                        namesSeen.Add(ed.ContractName); 
                    }
                } 
            } 

            return endpointContractNames.ToString(); 
        }

        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        { 
            ThrowIfNotAttachedToHost();
            ThrowIfNoMessageVersion(); 
 
            if (this.listener != null)
            { 
                try
                {
                    return this.listener.BeginOpen(timeout, callback, state);
                } 
                catch (InvalidOperationException e)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateOuterExceptionWithEndpointsInformation(e)); 
                }
            } 
            else
            {
                return new CompletedAsyncResult(callback, state);
            } 
        }
 
        protected override void OnEndOpen(IAsyncResult result) 
        {
            if (this.listener != null) 
            {
                try
                {
                    this.listener.EndOpen(result); 
                }
                catch (InvalidOperationException e) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateOuterExceptionWithEndpointsInformation(e));
                } 
            }
            else
            {
                CompletedAsyncResult.End(result); 
            }
        } 
 
        protected override void OnOpening()
        { 
            ThrowIfNotAttachedToHost();

            base.OnOpening();
        } 

        protected override void OnOpened() 
        { 
            ThrowIfNotAttachedToHost();
 
            base.OnOpened();

            this.errorBehavior = new ErrorBehavior(this);
 
            this.filterTable = new EndpointDispatcherTable(this.ThisLock);
            for (int i=0; i table) 
        {
            if (table == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("table");
            } 

            this.ThrowIfDisposedOrImmutable();

            this.addressTable = table; 
        }
 
        internal new void ThrowIfDisposedOrImmutable() 
        {
            base.ThrowIfDisposedOrImmutable(); 
            this.shared.ThrowIfImmutable();
        }

        void ThrowIfNotAttachedToHost() 
        {
            // if we are on the server, we need a host 
            // if we are on the client, we never call Open(), so this method is not invoked 
            if (this.host == null)
            { 
                Exception error = new InvalidOperationException(SR.GetString(SR.SFxChannelDispatcherNoHost0));
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error);
            }
        } 

        void ThrowIfNoMessageVersion() 
        { 
            if (this.messageVersion == null)
            { 
                Exception error = new InvalidOperationException(SR.GetString(SR.SFxChannelDispatcherNoMessageVersion));
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error);
            }
        } 

        void TraceEndpointLifetime(EndpointDispatcher endpoint, TraceCode traceCode) 
        { 
            if (DiagnosticUtility.ShouldTraceInformation)
            { 
                Dictionary values = new Dictionary(3);
                values["ContractNamespace"] = endpoint.ContractNamespace;
                values["ContractName"] = endpoint.ContractName;
                values["Endpoint"] = endpoint.ListenUri; 
                TraceUtility.TraceEvent(TraceEventType.Information, traceCode,
                                        new DictionaryTraceRecord(values), endpoint, null); 
            } 
        }
 
        protected override void Attach(ServiceHostBase host)
        {
            if (host == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("host");
            } 
 
            ServiceHostBase serviceHost = host;
 
            this.ThrowIfDisposedOrImmutable();

            if (this.host != null)
            { 
                Exception error = new InvalidOperationException(SR.GetString(SR.SFxChannelDispatcherMultipleHost0));
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error); 
            } 

            this.host = serviceHost; 
        }

        protected override void Detach(ServiceHostBase host)
        { 
            if (host == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("host"); 
            }
 
            if (this.host != host)
            {
                Exception error = new InvalidOperationException(SR.GetString(SR.SFxChannelDispatcherDifferentHost0));
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error); 
            }
 
            this.ThrowIfDisposedOrImmutable(); 

            this.host = null; 
        }

        class EndpointDispatcherCollection : SynchronizedCollection
        { 
            ChannelDispatcher owner;
 
            internal EndpointDispatcherCollection(ChannelDispatcher owner) 
                : base(owner.ThisLock)
            { 
                this.owner = owner;
            }

            protected override void ClearItems() 
            {
                foreach (EndpointDispatcher item in this.Items) 
                { 
                    this.owner.OnRemoveEndpoint(item);
                } 
                base.ClearItems();
            }

            protected override void InsertItem(int index, EndpointDispatcher item) 
            {
                if (item == null) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item"); 

                this.owner.OnAddEndpoint(item); 
                base.InsertItem(index, item);
            }

            protected override void RemoveItem(int index) 
            {
                EndpointDispatcher item = this.Items[index]; 
                base.RemoveItem(index); 
                this.owner.OnRemoveEndpoint(item);
            } 

            protected override void SetItem(int index, EndpointDispatcher item)
            {
                Exception error = new InvalidOperationException(SR.GetString(SR.SFxCollectionDoesNotSupportSet0)); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error);
            } 
        } 

        class ChannelDispatcherBehaviorCollection : SynchronizedCollection 
        {
            ChannelDispatcher outer;

            internal ChannelDispatcherBehaviorCollection(ChannelDispatcher outer) 
                : base(outer.ThisLock)
            { 
                this.outer = outer; 
            }
 
            protected override void ClearItems()
            {
                this.outer.ThrowIfDisposedOrImmutable();
                base.ClearItems(); 
            }
 
            protected override void InsertItem(int index, T item) 
            {
                if (item == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
                }
 
                this.outer.ThrowIfDisposedOrImmutable();
                base.InsertItem(index, item); 
            } 

            protected override void RemoveItem(int index) 
            {
                this.outer.ThrowIfDisposedOrImmutable();
                base.RemoveItem(index);
            } 

            protected override void SetItem(int index, T item) 
            { 
                if (item == null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
                }

                this.outer.ThrowIfDisposedOrImmutable(); 
                base.SetItem(index, item);
            } 
        } 
    }
} 

// 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