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

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

namespace System.ServiceModel 
{
    using System.Collections.Generic; 
    using System.ServiceModel.Dispatcher; 
    using System.Collections.ObjectModel;
    using System.Diagnostics; 
    using System.ServiceModel.Channels;
    using System.Threading;
    using System.Runtime.CompilerServices;
    using System.Runtime.Serialization; 
    using System.ServiceModel.Diagnostics;
 
    public sealed class InstanceContext : CommunicationObject, IExtensibleObject 
    {
        internal static InstanceContextEmptyCallback NotifyEmptyCallback = new InstanceContextEmptyCallback(InstanceContext.NotifyEmpty); 
        internal static InstanceContextIdleCallback NotifyIdleCallback = new InstanceContextIdleCallback(InstanceContext.NotifyIdle);

        bool autoClose;
        InstanceBehavior behavior; 
        ServiceChannelManager channels;
        ConcurrencyInstanceContextFacet concurrency; 
        ExtensionCollection extensions; 
        readonly ServiceHostBase host;
        QuotaThrottle quotaThrottle; 
        ServiceThrottle serviceThrottle;
        int instanceContextManagerIndex;
        object serviceInstanceLock = new object();
        SynchronizationContext synchronizationContext; 
        TransactionInstanceContextFacet transaction;
        object userObject; 
        bool wellKnown; 
        SynchronizedCollection wmiChannels;
        bool isUserCreated; 

        public InstanceContext(object implementation)
            : this(null, implementation)
        { 
        }
 
        public InstanceContext(ServiceHostBase host, object implementation) 
            : this(host, implementation, true)
        { 
        }

        internal InstanceContext(ServiceHostBase host, object implementation, bool isUserCreated)
            : this(host, implementation, true, isUserCreated) 
        {
        } 
 
        internal InstanceContext(ServiceHostBase host, object implementation, bool wellKnown, bool isUserCreated)
        { 
            this.host = host;
            if (implementation != null)
            {
                this.userObject = implementation; 
                this.wellKnown = wellKnown;
            } 
            this.autoClose = false; 
            this.channels = new ServiceChannelManager(this);
            this.isUserCreated = isUserCreated; 
        }

        public InstanceContext(ServiceHostBase host)
            : this(host, true) 
        {
        } 
 
        internal InstanceContext(ServiceHostBase host, bool isUserCreated)
        { 
            if (host == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("host"));

            this.host = host; 
            this.autoClose = true;
            this.channels = new ServiceChannelManager(this, NotifyEmptyCallback); 
            this.isUserCreated = isUserCreated; 
        }
 
        internal bool IsUserCreated
        {
            get { return this.isUserCreated; }
            set { this.isUserCreated = value; } 
        }
 
        internal bool IsWellKnown 
        {
            get { return this.wellKnown; } 
        }

        internal bool AutoClose
        { 
            get { return this.autoClose; }
            set { this.autoClose = value; } 
        } 

        internal InstanceBehavior Behavior 
        {
            get { return this.behavior; }
            set
            { 
                if (this.behavior == null)
                    this.behavior = value; 
            } 
        }
 
        internal ConcurrencyInstanceContextFacet Concurrency
        {
            get
            { 
                if (this.concurrency == null)
                { 
                    lock (this.ThisLock) 
                    {
                        if (this.concurrency == null) 
                            this.concurrency = new ConcurrencyInstanceContextFacet();
                    }
                }
 
                return this.concurrency;
            } 
        } 

        internal static InstanceContext Current 
        {
            get { return OperationContext.Current != null ? OperationContext.Current.InstanceContext : null; }
        }
 
        protected override TimeSpan DefaultCloseTimeout
        { 
            get 
            {
                if (this.host != null) 
                {
                    return this.host.CloseTimeout;
                }
                else 
                {
                    return ServiceDefaults.CloseTimeout; 
                } 
            }
        } 

        protected override TimeSpan DefaultOpenTimeout
        {
            get 
            {
                if (this.host != null) 
                { 
                    return this.host.OpenTimeout;
                } 
                else
                {
                    return ServiceDefaults.OpenTimeout;
                } 
            }
        } 
 
        public IExtensionCollection Extensions
        { 
            get
            {
                this.ThrowIfClosed();
                lock (this.ThisLock) 
                {
                    if (this.extensions == null) 
                        this.extensions = new ExtensionCollection(this, this.ThisLock); 
                    return this.extensions;
                } 
            }
        }

        internal bool HasTransaction 
        {
            get { return (this.transaction != null) && !object.Equals(this.transaction.Attached, null); } 
        } 

        public ICollection IncomingChannels 
        {
            get
            {
                this.ThrowIfClosed(); 
                return channels.IncomingChannels;
            } 
        } 

        bool IsBusy 
        {
            get
            {
                if (this.State == CommunicationState.Closed) 
                    return false;
                return this.channels.IsBusy; 
            } 
        }
 
        bool IsSingleton
        {
            get
            { 
                return ((this.behavior != null) &&
                        InstanceContextProviderBase.IsProviderSingleton(this.behavior.InstanceContextProvider)); 
            } 
        }
 
        public ICollection OutgoingChannels
        {
            get
            { 
                this.ThrowIfClosed();
                return channels.OutgoingChannels; 
            } 
        }
 
        public ServiceHostBase Host
        {
            get
            { 
                this.ThrowIfClosed();
                return this.host; 
            } 
        }
 
        public int ManualFlowControlLimit
        {
            get { return this.EnsureQuotaThrottle().Limit; }
            set { this.EnsureQuotaThrottle().SetLimit(value); } 
        }
 
        internal QuotaThrottle QuotaThrottle 
        {
            get { return this.quotaThrottle; } 
        }

        internal ServiceThrottle ServiceThrottle
        { 
            get { return this.serviceThrottle; }
            set 
            { 
                this.ThrowIfDisposed();
                this.serviceThrottle = value; 
            }
        }

        internal int InstanceContextManagerIndex 
        {
            get { return this.instanceContextManagerIndex; } 
            set { this.instanceContextManagerIndex = value; } 
        }
 
        public SynchronizationContext SynchronizationContext
        {
            get { return this.synchronizationContext; }
            set 
            {
                this.ThrowIfClosedOrOpened(); 
                this.synchronizationContext = value; 
            }
        } 

        new internal object ThisLock
        {
            get { return base.ThisLock; } 
        }
 
        internal TransactionInstanceContextFacet Transaction 
        {
            get 
            {
                if(this.transaction == null)
                {
                    lock (this.ThisLock) 
                    {
                        if (this.transaction == null) 
                            this.transaction = new TransactionInstanceContextFacet(this); 
                    }
                } 

                return this.transaction;
            }
        } 

        internal object UserObject 
        { 
            get { return this.userObject; }
        } 

        internal ICollection WmiChannels
        {
            get 
            {
                if (this.wmiChannels == null) 
                { 
                    lock (this.ThisLock)
                    { 
                        if (this.wmiChannels == null)
                        {
                            this.wmiChannels = new SynchronizedCollection();
                        } 
                    }
                } 
                return this.wmiChannels; 
            }
        } 

        protected override void OnAbort()
        {
            channels.Abort(); 

            this.Unload(); 
        } 

        internal IAsyncResult BeginCloseInput(TimeSpan timeout, AsyncCallback callback, object state) 
        {
            return channels.BeginCloseInput(timeout, callback, state);
        }
 
        internal void BindRpc(ref MessageRpc rpc)
        { 
            this.ThrowIfDisposed(); 
            this.channels.IncrementActivityCount();
            rpc.SuccessfullyBoundInstance = true; 
        }

        internal void BindIncomingChannel(ServiceChannel channel)
        { 
            this.ThrowIfDisposed();
 
            channel.InstanceContext = this; 
            this.channels.AddIncomingChannel((IChannel)channel.Proxy);
        } 


        void CloseIfNotBusy()
        { 
            if (!(this.State != CommunicationState.Created && this.State != CommunicationState.Opening))
            { 
                DiagnosticUtility.DebugAssert("InstanceContext.CloseIfNotBusy: (this.State != CommunicationState.Created && this.State != CommunicationState.Opening)"); 
            }
 
            if (this.State != CommunicationState.Opened)
                return;

            if (this.IsBusy) 
                return;
 
            if (this.behavior.CanUnload(this) == false) 
                return;
 
            try
            {
                if (this.State == CommunicationState.Opened)
                    this.Close(); 
            }
            catch (ObjectDisposedException e) 
            { 
                if (DiagnosticUtility.ShouldTraceInformation)
                { 
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information);
                }
            }
            catch (InvalidOperationException e) 
            {
                if (DiagnosticUtility.ShouldTraceInformation) 
                { 
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information);
                } 
            }
            catch (CommunicationException e)
            {
                if (DiagnosticUtility.ShouldTraceInformation) 
                {
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); 
                } 
            }
            catch (TimeoutException e) 
            {
                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); 
                }
            } 
        } 

        internal void CloseInput(TimeSpan timeout) 
        {
            channels.CloseInput(timeout);
        }
 
        internal void EndCloseInput(IAsyncResult result)
        { 
            channels.EndCloseInput(result); 
        }
 
        [MethodImpl(MethodImplOptions.NoInlining)]
        internal void CompleteAttachedTransaction()
        {
            Exception error = null; 

            if(!this.behavior.TransactionAutoCompleteOnSessionClose) 
            { 
                error = new Exception();
                if(DiagnosticUtility.ShouldTraceInformation) 
                    DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Information,
                                                                    TraceCode.TxCompletionStatusAbortedOnSessionClose,
                                                                    SR.GetString(SR.TraceCodeTxCompletionStatusAbortedOnSessionClose,
                                                                                    transaction.Attached.TransactionInformation.LocalIdentifier) 
                                                                    );
 
            } 
            else if(DiagnosticUtility.ShouldTraceInformation)
            { 
                DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Information,
                                                                TraceCode.TxCompletionStatusCompletedForTACOSC,
                                                                SR.GetString(SR.TraceCodeTxCompletionStatusCompletedForTACOSC,
                                                                                transaction.Attached.TransactionInformation.LocalIdentifier) 
                                                                );
            } 
 
            transaction.CompletePendingTransaction(transaction.Attached, error);
            transaction.Attached = null; 
        }

        QuotaThrottle EnsureQuotaThrottle()
        { 
            lock (this.ThisLock)
            { 
                if (this.quotaThrottle == null) 
                {
                    this.quotaThrottle = new QuotaThrottle(ImmutableDispatchRuntime.GotDynamicInstanceContext, this.ThisLock); 
                    this.quotaThrottle.Owner = "InstanceContext";
                }
                return this.quotaThrottle;
            } 
        }
 
        internal void FaultInternal() 
        {
            this.Fault(); 
        }

        public object GetServiceInstance()
        { 
            return this.GetServiceInstance(null);
        } 
 
        public object GetServiceInstance(Message message)
        { 
            lock (this.serviceInstanceLock)
            {
                this.ThrowIfClosedOrNotOpen();
 
                object current = this.userObject;
                if (current != null) 
                    return current; 

                if (this.behavior == null) 
                {
                    Exception error = new InvalidOperationException(SR.GetString(SR.SFxInstanceNotInitialized));
                    if (message != null)
                    { 
                        throw TraceUtility.ThrowHelperError(error, message);
                    } 
                    else 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error); 
                    }
                }

                object newUserObject; 
                if (message != null)
                { 
                    newUserObject = this.behavior.GetInstance(this, message); 
                }
                else 
                {
                    newUserObject = this.behavior.GetInstance(this);
                }
                if (newUserObject != null) 
                    this.SetUserObject(newUserObject);
 
                return newUserObject; 
            }
        } 

        public int IncrementManualFlowControlLimit(int incrementBy)
        {
            return this.EnsureQuotaThrottle().IncrementLimit(incrementBy); 
        }
 
        void Load() 
        {
            if (this.behavior != null) 
                this.behavior.Initialize(this);

            if (this.host != null)
                this.host.BindInstance(this); 
        }
 
        static void NotifyEmpty(InstanceContext instanceContext) 
        {
            if (instanceContext.autoClose) 
                instanceContext.CloseIfNotBusy();
        }

        static void NotifyIdle(InstanceContext instanceContext) 
        {
            instanceContext.CloseIfNotBusy(); 
        } 

        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 
        {
            return new CloseAsyncResult(timeout, callback, state, this);
        }
 
        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        { 
            return new CompletedAsyncResult(callback, state); 
        }
 
        protected override void OnClose(TimeSpan timeout)
        {
            channels.Close(timeout);
            this.Unload(); 
        }
 
        protected override void OnClosed() 
        {
            base.OnClosed(); 

            ServiceThrottle throttle = this.serviceThrottle;
            if (throttle != null)
                throttle.DeactivateInstanceContext(); 
        }
 
        protected override void OnEndClose(IAsyncResult result) 
        {
            CloseAsyncResult.End(result); 
        }

        protected override void OnEndOpen(IAsyncResult result)
        { 
            CompletedAsyncResult.End(result);
        } 
 
        protected override void OnFaulted()
        { 
            base.OnFaulted();

            if (this.IsSingleton && (this.host != null))
            { 
                this.host.FaultInternal();
            } 
        } 

        protected override void OnOpen(TimeSpan timeout) 
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
        }
 
        protected override void OnOpened()
        { 
            base.OnOpened(); 
        }
 
        protected override void OnOpening()
        {
            this.Load();
            base.OnOpening(); 
        }
 
        public void ReleaseServiceInstance() 
        {
            this.ThrowIfDisposedOrNotOpen(); 
            this.SetUserObject(null);
        }

        void SetUserObject(object newUserObject) 
        {
            if (this.behavior != null && !this.wellKnown) 
            { 
                object oldUserObject = Interlocked.Exchange(ref this.userObject, newUserObject);
 
                if ((oldUserObject != null) && (this.host != null) && !Object.Equals(oldUserObject, this.host.DisposableInstance))
                {
                    this.behavior.ReleaseInstance(this, oldUserObject);
                } 
            }
        } 
 
        internal void UnbindRpc(ref MessageRpc rpc)
        { 
            if (rpc.InstanceContext == this && rpc.SuccessfullyBoundInstance)
            {
                this.channels.DecrementActivityCount();
            } 
        }
 
        internal void UnbindIncomingChannel(ServiceChannel channel) 
        {
            this.channels.RemoveChannel((IChannel)channel.Proxy); 
        }

        void Unload()
        { 
            this.SetUserObject(null);
 
            if (this.host != null) 
                this.host.UnbindInstance(this);
        } 

        // -----------------------------------------------------------------------------------------------------------

        class CloseAsyncResult : AsyncResult 
        {
            InstanceContext instanceContext; 
            TimeoutHelper timeoutHelper; 

            public CloseAsyncResult(TimeSpan timeout, AsyncCallback callback, object state, InstanceContext instanceContext) 
                : base(callback, state)
            {
                this.timeoutHelper = new TimeoutHelper(timeout);
                this.instanceContext = instanceContext; 

                CloseChannels(); 
            } 

            void CloseChannels() 
            {
                IAsyncResult result = instanceContext.channels.BeginClose(this.timeoutHelper.RemainingTime(), DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(CloseChannelsCallback)), this);
                if (!result.CompletedSynchronously)
                    return; 

                instanceContext.channels.EndClose(result); 
                instanceContext.Unload(); 
                Complete(true);
            } 

            void CloseChannelsCallback(IAsyncResult result)
            {
                if (result.CompletedSynchronously) 
                    return;
                Exception completionException = null; 
                CloseAsyncResult closeResult = (CloseAsyncResult)result.AsyncState; 
                try
                { 
                    closeResult.instanceContext.channels.EndClose(result);
                    closeResult.instanceContext.Unload();
                }
#pragma warning suppress 56500 // covered by FxCOP 
                catch (Exception e)
                { 
                    if (DiagnosticUtility.IsFatal(e)) 
                    {
                        throw; 
                    }

                    completionException = e;
                } 

                closeResult.Complete(false, completionException); 
            } 

            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