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

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Channels
{ 
    using System.Collections.Generic;
    using System.ServiceModel; 
    using System.Diagnostics; 
    using System.ServiceModel.Diagnostics;
 
    public abstract class CommunicationObject : ICommunicationObject
    {
        bool aborted;
        bool closeCalled; 
#if DEBUG
        StackTrace closeStack; 
        StackTrace faultedStack; 
#endif
        ExceptionQueue exceptionQueue; 
        object mutex;
        bool onClosingCalled;
        bool onClosedCalled;
        bool onOpeningCalled; 
        bool onOpenedCalled;
        bool raisedClosed; 
        bool raisedClosing; 
        bool raisedFaulted;
        bool traceOpenAndClose; 
        object eventSender;
        CommunicationState state;

        protected CommunicationObject() 
            : this(new object())
        { 
        } 

        protected CommunicationObject(object mutex) 
        {
            this.mutex = mutex;
            this.eventSender = this;
            this.state = CommunicationState.Created; 
        }
 
        internal CommunicationObject(object mutex, object eventSender) 
        {
            this.mutex = mutex; 
            this.eventSender = eventSender;
            this.state = CommunicationState.Created;
        }
 
        internal bool Aborted
        { 
            get { return this.aborted; } 
        }
 
        internal object EventSender
        {
            get { return this.eventSender; }
            set { eventSender = value; } 
        }
 
        protected bool IsDisposed 
        {
            get { return this.state == CommunicationState.Closed; } 
        }

        public CommunicationState State
        { 
            get { return this.state; }
        } 
 
        protected object ThisLock
        { 
            get { return this.mutex; }
        }

        protected abstract TimeSpan DefaultCloseTimeout { get; } 
        protected abstract TimeSpan DefaultOpenTimeout { get; }
 
        internal TimeSpan InternalCloseTimeout 
        {
            get { return this.DefaultCloseTimeout; } 
        }

        internal TimeSpan InternalOpenTimeout
        { 
            get { return this.DefaultOpenTimeout; }
        } 
 
        public event EventHandler Closed;
        public event EventHandler Closing; 
        public event EventHandler Faulted;
        public event EventHandler Opened;
        public event EventHandler Opening;
 
        public void Abort()
        { 
            lock (ThisLock) 
            {
                if (this.aborted || this.state == CommunicationState.Closed) 
                    return;
                this.aborted = true;
#if DEBUG
                if (closeStack == null) 
                    closeStack = new StackTrace();
#endif 
 
                this.state = CommunicationState.Closing;
            } 

            if (DiagnosticUtility.ShouldTraceInformation)
                DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Information, TraceCode.CommunicationObjectAborted, SR.GetString(SR.TraceCodeCommunicationObjectAborted, DiagnosticTrace.CreateSourceString(this)), null, null, this);
 
            bool throwing = true;
 
            try 
            {
                OnClosing(); 
                if (!this.onClosingCalled)
                    throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosing"), Guid.Empty, this);

                OnAbort(); 

                OnClosed(); 
                if (!this.onClosedCalled) 
                    throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosed"), Guid.Empty, this);
 
                throwing = false;
            }
            finally
            { 
                if (throwing)
                { 
                    if (DiagnosticUtility.ShouldTraceWarning) 
                        DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectAbortFailed, SR.GetString(SR.TraceCodeCommunicationObjectAbortFailed, this.GetCommunicationObjectType().ToString()), null, null, this);
                } 
            }
        }

 
        public IAsyncResult BeginClose(AsyncCallback callback, object state)
        { 
            return this.BeginClose(this.DefaultCloseTimeout, callback, state); 
        }
 
        public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
        {
            if (timeout < TimeSpan.Zero)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new ArgumentOutOfRangeException("timeout", SR.GetString(SR.SFxTimeoutOutOfRange0)));
 
            using (DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? this.CreateCloseActivity() : null) 
            {
                CommunicationState originalState; 
                lock (ThisLock)
                {
                    originalState = this.state;
#if DEBUG 
                    if (closeStack == null)
                        closeStack = new StackTrace(); 
#endif 
                    if (originalState != CommunicationState.Closed)
                        this.state = CommunicationState.Closing; 

                    this.closeCalled = true;
                }
 
                switch (originalState)
                { 
                    case CommunicationState.Created: 
                    case CommunicationState.Opening:
                    case CommunicationState.Faulted: 
                        this.Abort();
                        if (originalState == CommunicationState.Faulted)
                        {
                            throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this); 
                        }
                        return new AlreadyClosedAsyncResult(callback, state); 
 
                    case CommunicationState.Opened:
                        { 
                            bool throwing = true;
                            try
                            {
                                OnClosing(); 
                                if (!this.onClosingCalled)
                                    throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosing"), Guid.Empty, this); 
 
                                IAsyncResult result = new CloseAsyncResult(this, timeout, callback, state);
                                throwing = false; 
                                return result;
                            }
                            finally
                            { 
                                if (throwing)
                                { 
                                    if (DiagnosticUtility.ShouldTraceWarning) 
                                        DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectCloseFailed, SR.GetString(SR.TraceCodeCommunicationObjectCloseFailed, this.GetCommunicationObjectType().ToString()), null, null, this);
 
                                    Abort();
                                }
                            }
                        } 

                    case CommunicationState.Closing: 
                    case CommunicationState.Closed: 
                        return new AlreadyClosedAsyncResult(callback, state);
 
                    default:
                        DiagnosticUtility.DebugAssert("CommunicationObject.BeginClose: Unknown CommunicationState");
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
                } 
            }
        } 
 
        public IAsyncResult BeginOpen(AsyncCallback callback, object state)
        { 
            return this.BeginOpen(this.DefaultOpenTimeout, callback, state);
        }

        public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state) 
        {
            if (timeout < TimeSpan.Zero) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new ArgumentOutOfRangeException("timeout", SR.GetString(SR.SFxTimeoutOutOfRange0)));
 
            lock (ThisLock)
            {
                ThrowIfDisposedOrImmutable();
                this.state = CommunicationState.Opening; 
            }
 
            bool throwing = true; 
            try
            { 
                OnOpening();
                if(!this.onOpeningCalled)
                    throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnOpening"), Guid.Empty, this);
 
                IAsyncResult result = new OpenAsyncResult(this, timeout, callback, state);
                throwing = false; 
                return result; 
            }
            finally 
            {
                if (throwing)
                {
                    if (DiagnosticUtility.ShouldTraceWarning) 
                        DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectOpenFailed, SR.GetString(SR.TraceCodeCommunicationObjectOpenFailed, this.GetCommunicationObjectType().ToString()), null, null, this);
 
                    Fault(); 
                }
            } 
        }

        public void Close()
        { 
            this.Close(this.DefaultCloseTimeout);
        } 
 
        public void Close(TimeSpan timeout)
        { 
            if (timeout < TimeSpan.Zero)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new ArgumentOutOfRangeException("timeout", SR.GetString(SR.SFxTimeoutOutOfRange0)));
 
            using (DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? this.CreateCloseActivity() : null)
            { 
 
                CommunicationState originalState;
                lock (ThisLock) 
                {
                    originalState = this.state;
#if DEBUG
                    if (closeStack == null) 
                        closeStack = new StackTrace();
#endif 
                    if (originalState != CommunicationState.Closed) 
                        this.state = CommunicationState.Closing;
 
                    this.closeCalled = true;
                }

                switch (originalState) 
                {
                    case CommunicationState.Created: 
                    case CommunicationState.Opening: 
                    case CommunicationState.Faulted:
                        this.Abort(); 
                        if (originalState == CommunicationState.Faulted)
                        {
                            throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
                        } 
                        break;
 
                    case CommunicationState.Opened: 
                        {
                            bool throwing = true; 
                            try
                            {
                                OnClosing();
                                if (!this.onClosingCalled) 
                                    throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosing"), Guid.Empty, this);
 
                                OnClose(timeout); 
                                OnClosed();
                                if (!this.onClosedCalled) 
                                    throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosed"), Guid.Empty, this);

                                throwing = false;
                            } 
                            finally
                            { 
                                if (throwing) 
                                {
                                    if (DiagnosticUtility.ShouldTraceWarning) 
                                        DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectCloseFailed, SR.GetString(SR.TraceCodeCommunicationObjectCloseFailed, this.GetCommunicationObjectType().ToString()), null, null, this);

                                    Abort();
                                } 
                            }
                            break; 
                        } 

                    case CommunicationState.Closing: 
                    case CommunicationState.Closed:
                        break;

                    default: 
                        DiagnosticUtility.DebugAssert("CommunicationObject.BeginClose: Unknown CommunicationState");
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
                } 
            }
        } 

        Exception CreateNotOpenException()
        {
            return new InvalidOperationException(SR.GetString(SR.CommunicationObjectCannotBeUsed, this.GetCommunicationObjectType().ToString(), this.state.ToString())); 
        }
 
        Exception CreateImmutableException() 
        {
            return new InvalidOperationException(SR.GetString(SR.CommunicationObjectCannotBeModifiedInState, this.GetCommunicationObjectType().ToString(), this.state.ToString())); 
        }

        Exception CreateBaseClassMethodNotCalledException(string method)
        { 
            return new InvalidOperationException(SR.GetString(SR.CommunicationObjectBaseClassMethodNotCalled, this.GetCommunicationObjectType().ToString(), method));
        } 
 
        internal Exception CreateClosedException()
        { 
            if (!this.closeCalled)
            {
                return CreateAbortedException();
            } 
            else
            { 
#if DEBUG 
                string originalStack = closeStack.ToString().Replace("\r\n", "\r\n    ");
                return new ObjectDisposedException(this.GetCommunicationObjectType().ToString() + ", Object already closed:\r\n    " + originalStack); 
#else
                return new ObjectDisposedException(this.GetCommunicationObjectType().ToString());
#endif
            } 
        }
 
        Exception CreateFaultedException() 
        {
#if DEBUG 
            string originalStack = faultedStack.ToString().Replace("\r\n", "\r\n    ");
            string message = SR.GetString(SR.CommunicationObjectFaultedStack2, this.GetCommunicationObjectType().ToString(), originalStack);
#else
            string message = SR.GetString(SR.CommunicationObjectFaulted1, this.GetCommunicationObjectType().ToString()); 
#endif
            return new CommunicationObjectFaultedException(message); 
        } 

        internal Exception CreateAbortedException() 
        {
#if DEBUG
            string originalStack = closeStack.ToString().Replace("\r\n", "\r\n    ");
            return new CommunicationObjectAbortedException(SR.GetString(SR.CommunicationObjectAbortedStack2, this.GetCommunicationObjectType().ToString(), originalStack)); 
#else
            return new CommunicationObjectAbortedException(SR.GetString(SR.CommunicationObjectAborted1, this.GetCommunicationObjectType().ToString())); 
#endif 
        }
 
        internal virtual string CloseActivityName
        {
            get { return SR.GetString(SR.ActivityClose, this.GetType().FullName); }
        } 

        internal virtual string OpenActivityName 
        { 
            get { return SR.GetString(SR.ActivityOpen, this.GetType().FullName); }
        } 

        internal virtual ActivityType OpenActivityType
        {
            get { return ActivityType.Open; } 
        }
 
        ServiceModelActivity CreateCloseActivity() 
        {
            ServiceModelActivity retval = null; 
            retval = ServiceModelActivity.CreateBoundedActivity();
            if (DiagnosticUtility.ShouldUseActivity)
            {
                ServiceModelActivity.Start(retval, this.CloseActivityName, ActivityType.Close); 
            }
 
            return retval; 
        }
 
        internal bool DoneReceivingInCurrentState()
        {
            this.ThrowPending();
 
            switch (this.state)
            { 
                case CommunicationState.Created: 
                    throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
 
                case CommunicationState.Opening:
                    throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);

                case CommunicationState.Opened: 
                    return false;
 
                case CommunicationState.Closing: 
                    return true;
 
                case CommunicationState.Closed:
                    return true;

                case CommunicationState.Faulted: 
                    return true;
 
                default: 
                    DiagnosticUtility.DebugAssert("DoneReceivingInCurrentState: Unknown CommunicationObject.state");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            }
        }

        public void EndClose(IAsyncResult result) 
        {
            if (result is AlreadyClosedAsyncResult) 
                AlreadyClosedAsyncResult.End(result); 
            else
                CloseAsyncResult.End(result); 
        }

        public void EndOpen(IAsyncResult result)
        { 
            OpenAsyncResult.End(result);
        } 
 
        protected void Fault()
        { 
            lock (ThisLock)
            {
                if (this.state == CommunicationState.Closed || this.state == CommunicationState.Closing)
                    return; 

                if (this.state == CommunicationState.Faulted) 
                    return; 
#if DEBUG
                if (faultedStack == null) 
                    faultedStack = new StackTrace();
#endif
                this.state = CommunicationState.Faulted;
            } 

            OnFaulted(); 
        } 

        internal void Fault(Exception exception) 
        {
            lock (this.ThisLock)
            {
                if (this.exceptionQueue == null) 
                    this.exceptionQueue = new ExceptionQueue(this.ThisLock);
            } 
 
            if (exception != null && DiagnosticUtility.ShouldTraceInformation)
            { 
                TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.CommunicationObjectFaultReason, exception, null);
            }

            this.exceptionQueue.AddException(exception); 
            this.Fault();
        } 
 
        internal void AddPendingException(Exception exception)
        { 
            lock (this.ThisLock)
            {
                if (this.exceptionQueue == null)
                    this.exceptionQueue = new ExceptionQueue(this.ThisLock); 
            }
 
            this.exceptionQueue.AddException(exception); 
        }
 
        internal Exception GetPendingException()
        {
            CommunicationState currentState = this.state;
 
            DiagnosticUtility.DebugAssert(currentState == CommunicationState.Closing || currentState == CommunicationState.Closed || currentState == CommunicationState.Faulted,
                "CommunicationObject.GetPendingException(currentState == CommunicationState.Closing || currentState == CommunicationState.Closed || currentState == CommunicationState.Faulted)"); 
 
            ExceptionQueue queue = this.exceptionQueue;
            if (queue != null) 
            {
                return queue.GetException();
            }
            else 
            {
                return null; 
            } 
        }
 
        internal Exception GetTerminalException()
        {
            Exception exception = this.GetPendingException();
 
            if (exception == null)
            { 
                exception = CreateFaultedException(); 
            }
 
            return exception;
        }

        public void Open() 
        {
            this.Open(this.DefaultOpenTimeout); 
        } 

        public void Open(TimeSpan timeout) 
        {
            if (timeout < TimeSpan.Zero)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new ArgumentOutOfRangeException("timeout", SR.GetString(SR.SFxTimeoutOutOfRange0))); 

            using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? ServiceModelActivity.CreateBoundedActivity() : null) 
            { 
                if (DiagnosticUtility.ShouldUseActivity)
                { 
                    ServiceModelActivity.Start(activity, this.OpenActivityName, this.OpenActivityType);
                }
                lock (ThisLock)
                { 
                    ThrowIfDisposedOrImmutable();
                    this.state = CommunicationState.Opening; 
                } 

                bool throwing = true; 
                try
                {
                    OnOpening();
                    if (!this.onOpeningCalled) 
                        throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnOpening"), Guid.Empty, this);
 
                    OnOpen(timeout); 
                    OnOpened();
                    if (!this.onOpenedCalled) 
                        throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnOpened"), Guid.Empty, this);

                    throwing = false;
                } 
                finally
                { 
                    if (throwing) 
                    {
                        if (DiagnosticUtility.ShouldTraceWarning) 
                            DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectOpenFailed, SR.GetString(SR.TraceCodeCommunicationObjectOpenFailed, this.GetCommunicationObjectType().ToString()), null, null, this);

                        Fault();
                    } 
                }
            } 
        } 

        protected virtual void OnClosed() 
        {
            this.onClosedCalled = true;

            lock (ThisLock) 
            {
                if (this.raisedClosed) 
                    return; 
                this.raisedClosed = true;
                this.state = CommunicationState.Closed; 
            }

            if (DiagnosticUtility.ShouldTraceVerbose)
                DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectClosed, SR.GetString(SR.TraceCodeCommunicationObjectClosed, DiagnosticTrace.CreateSourceString(this)), null, null, this); 

            EventHandler handler = Closed; 
            if (handler != null) 
            {
                try 
                {
                    handler(eventSender, EventArgs.Empty);
                }
                catch (Exception exception) 
                {
                    if (DiagnosticUtility.IsFatal(exception)) 
                        throw; 

                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception); 
                }
            }
        }
 
        protected virtual void OnClosing()
        { 
            this.onClosingCalled = true; 

            lock (ThisLock) 
            {
                if (this.raisedClosing)
                    return;
                this.raisedClosing = true; 
            }
 
            if (DiagnosticUtility.ShouldTraceVerbose) 
            {
                DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectClosing, SR.GetString(SR.TraceCodeCommunicationObjectClosing, DiagnosticTrace.CreateSourceString(this)), null, null, this); 
            }
            EventHandler handler = Closing;
            if (handler != null)
            { 
                try
                { 
                    handler(eventSender, EventArgs.Empty); 
                }
                catch (Exception exception) 
                {
                    if (DiagnosticUtility.IsFatal(exception))
                        throw;
 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
                } 
            } 
        }
 
        protected virtual void OnFaulted()
        {
            lock (ThisLock)
            { 
                if (this.raisedFaulted)
                    return; 
                this.raisedFaulted = true; 
            }
 
            if (DiagnosticUtility.ShouldTraceWarning)
            {
                DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectFaulted, SR.GetString(SR.TraceCodeCommunicationObjectFaulted, this.GetCommunicationObjectType().ToString()), null, null, this);
            } 

            EventHandler handler = Faulted; 
            if (handler != null) 
            {
                try 
                {
                    handler(eventSender, EventArgs.Empty);
                }
                catch (Exception exception) 
                {
                    if (DiagnosticUtility.IsFatal(exception)) 
                        throw; 

                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception); 
                }
            }
        }
 
        protected virtual void OnOpened()
        { 
            this.onOpenedCalled = true; 

            lock (ThisLock) 
            {
                if (this.aborted || this.state != CommunicationState.Opening)
                    return;
                this.state = CommunicationState.Opened; 
            }
 
            if (DiagnosticUtility.ShouldTraceVerbose) 
                DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectOpened, SR.GetString(SR.TraceCodeCommunicationObjectOpened, DiagnosticTrace.CreateSourceString(this)), null, null, this);
 
            EventHandler handler = Opened;
            if (handler != null)
            {
                try 
                {
                    handler(eventSender, EventArgs.Empty); 
                } 
                catch (Exception exception)
                { 
                    if (DiagnosticUtility.IsFatal(exception))
                        throw;

                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception); 
                }
            } 
        } 

        protected virtual void OnOpening() 
        {
            this.onOpeningCalled = true;

            if (DiagnosticUtility.ShouldTraceVerbose) 
                DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectOpening, SR.GetString(SR.TraceCodeCommunicationObjectOpening, DiagnosticTrace.CreateSourceString(this)), null, null, this);
 
            EventHandler handler = Opening; 
            if (handler != null)
            { 
                try
                {
                    handler(eventSender, EventArgs.Empty);
                } 
                catch (Exception exception)
                { 
                    if (DiagnosticUtility.IsFatal(exception)) 
                        throw;
 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
                }
            }
        } 

        internal void ThrowIfFaulted() 
        { 
            this.ThrowPending();
 
            switch (this.state)
            {
                case CommunicationState.Created:
                    break; 

                case CommunicationState.Opening: 
                    break; 

                case CommunicationState.Opened: 
                    break;

                case CommunicationState.Closing:
                    break; 

                case CommunicationState.Closed: 
                    break; 

                case CommunicationState.Faulted: 
                    throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);

                default:
                    DiagnosticUtility.DebugAssert("ThrowIfFaulted: Unknown CommunicationObject.state"); 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
            } 
        } 

        internal void ThrowIfAborted() 
        {
            if(this.aborted && !this.closeCalled)
            {
                throw TraceUtility.ThrowHelperError(CreateAbortedException(), Guid.Empty, this); 
            }
        } 
 
        internal bool TraceOpenAndClose
        { 
            get
            {
                return this.traceOpenAndClose;
            } 
            set
            { 
                this.traceOpenAndClose = value && DiagnosticUtility.ShouldUseActivity; 
            }
        } 

        internal void ThrowIfClosed()
        {
            ThrowPending(); 

            switch (this.state) 
            { 
                case CommunicationState.Created:
                    break; 

                case CommunicationState.Opening:
                    break;
 
                case CommunicationState.Opened:
                    break; 
 
                case CommunicationState.Closing:
                    break; 

                case CommunicationState.Closed:
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
 
                case CommunicationState.Faulted:
                    throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this); 
 
                default:
                    DiagnosticUtility.DebugAssert("ThrowIfClosed: Unknown CommunicationObject.state"); 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
            }
        }
 
        protected virtual Type GetCommunicationObjectType()
        { 
            return this.GetType(); 
        }
 
        protected internal void ThrowIfDisposed()
        {
            ThrowPending();
 
            switch (this.state)
            { 
                case CommunicationState.Created: 
                    break;
 
                case CommunicationState.Opening:
                    break;

                case CommunicationState.Opened: 
                    break;
 
                case CommunicationState.Closing: 
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
 
                case CommunicationState.Closed:
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);

                case CommunicationState.Faulted: 
                    throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
 
                default: 
                    DiagnosticUtility.DebugAssert("ThrowIfDisposed: Unknown CommunicationObject.state");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            }
        }

        internal void ThrowIfClosedOrOpened() 
        {
            ThrowPending(); 
 
            switch (this.state)
            { 
                case CommunicationState.Created:
                    break;

                case CommunicationState.Opening: 
                    break;
 
                case CommunicationState.Opened: 
                    throw TraceUtility.ThrowHelperError(this.CreateImmutableException(), Guid.Empty, this);
 
                case CommunicationState.Closing:
                    throw TraceUtility.ThrowHelperError(this.CreateImmutableException(), Guid.Empty, this);

                case CommunicationState.Closed: 
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
 
                case CommunicationState.Faulted: 
                    throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
 
                default:
                    DiagnosticUtility.DebugAssert("ThrowIfClosedOrOpened: Unknown CommunicationObject.state");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
            } 
        }
 
        protected internal void ThrowIfDisposedOrImmutable() 
        {
            ThrowPending(); 

            switch (this.state)
            {
                case CommunicationState.Created: 
                    break;
 
                case CommunicationState.Opening: 
                    throw TraceUtility.ThrowHelperError(this.CreateImmutableException(), Guid.Empty, this);
 
                case CommunicationState.Opened:
                    throw TraceUtility.ThrowHelperError(this.CreateImmutableException(), Guid.Empty, this);

                case CommunicationState.Closing: 
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
 
                case CommunicationState.Closed: 
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
 
                case CommunicationState.Faulted:
                    throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);

                default: 
                    DiagnosticUtility.DebugAssert("ThrowIfDisposedOrImmutable: Unknown CommunicationObject.state");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            } 
        }
 
        protected internal void ThrowIfDisposedOrNotOpen()
        {
            ThrowPending();
 
            switch (this.state)
            { 
                case CommunicationState.Created: 
                    throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
 
                case CommunicationState.Opening:
                    throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);

                case CommunicationState.Opened: 
                    break;
 
                case CommunicationState.Closing: 
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
 
                case CommunicationState.Closed:
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);

                case CommunicationState.Faulted: 
                    throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
 
                default: 
                    DiagnosticUtility.DebugAssert("ThrowIfDisposedOrNotOpen: Unknown CommunicationObject.state");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            }
        }

        internal void ThrowIfNotOpened() 
        {
            if(this.state == CommunicationState.Created || this.state == CommunicationState.Opening) 
                throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this); 
        }
 
        internal void ThrowIfClosedOrNotOpen()
        {
            ThrowPending();
 
            switch (this.state)
            { 
                case CommunicationState.Created: 
                    throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
 
                case CommunicationState.Opening:
                    throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);

                case CommunicationState.Opened: 
                    break;
 
                case CommunicationState.Closing: 
                    break;
 
                case CommunicationState.Closed:
                    throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);

                case CommunicationState.Faulted: 
                    throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
 
                default: 
                    DiagnosticUtility.DebugAssert("ThrowIfClosedOrNotOpen: Unknown CommunicationObject.state");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
            }
        }

        internal void ThrowPending() 
        {
            ExceptionQueue queue = this.exceptionQueue; 
 
            if (queue != null)
            { 
                Exception exception = queue.GetException();

                if (exception != null)
                { 
                    throw TraceUtility.ThrowHelperError(exception, Guid.Empty, this);
                } 
            } 
        }
 
        //
        // State callbacks
        //
 
        protected abstract void OnAbort();
 
        protected abstract void OnClose(TimeSpan timeout); 
        protected abstract void OnEndClose(IAsyncResult result);
        protected abstract IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state); 

        protected abstract void OnOpen(TimeSpan timeout);
        protected abstract IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state);
        protected abstract void OnEndOpen(IAsyncResult result); 

        class AlreadyClosedAsyncResult : CompletedAsyncResult 
        { 
            public AlreadyClosedAsyncResult(AsyncCallback callback, object state)
                : base(callback, state) 
            {
            }
        }
 
        class ExceptionQueue
        { 
            Queue exceptions = new Queue(); 
            object thisLock;
 
            internal ExceptionQueue(object thisLock)
            {
                this.thisLock = thisLock;
            } 

            object ThisLock 
            { 
                get { return this.thisLock; }
            } 

            public void AddException(Exception exception)
            {
                if (exception == null) 
                {
                    return; 
                } 

                lock (this.ThisLock) 
                {
                    this.exceptions.Enqueue(exception);
                }
            } 

            public Exception GetException() 
            { 
                lock (this.ThisLock)
                { 
                    if (this.exceptions.Count > 0)
                    {
                        return this.exceptions.Dequeue();
                    } 
                }
 
                return null; 
            }
        } 

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

                IAsyncResult result = this.communicationObject.OnBeginOpen(timeout, onOpenComplete, this);
                if (result.CompletedSynchronously) 
                {
                    this.HandleOpenComplete(result); 
                    this.Complete(true); 
                }
            } 

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

                    if (DiagnosticUtility.ShouldTraceWarning)
                    { 
                        DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning,
                            TraceCode.CommunicationObjectOpenFailed, 
                            SR.GetString(SR.TraceCodeCommunicationObjectOpenFailed, 
                            thisPtr.communicationObject.GetCommunicationObjectType().ToString()),
                            null, null, thisPtr); 
                    }

                    thisPtr.communicationObject.Fault();
                } 

                thisPtr.Complete(false, exception); 
            } 

            void HandleOpenComplete(IAsyncResult result) 
            {
                this.communicationObject.OnEndOpen(result);
                this.communicationObject.OnOpened();
                if (!this.communicationObject.onOpenedCalled) 
                {
                    throw TraceUtility.ThrowHelperError( 
                        this.communicationObject.CreateBaseClassMethodNotCalledException("OnOpened"), 
                        Guid.Empty, this.communicationObject);
                } 
            }

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

        class CloseAsyncResult : TraceAsyncResult 
        {
            CommunicationObject communicationObject;
            static AsyncCallback onCloseComplete = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnCloseComplete));
 
            public CloseAsyncResult(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state) 
            { 
                this.communicationObject = communicationObject;
 
                IAsyncResult result = this.communicationObject.OnBeginClose(timeout, onCloseComplete, this);
                if (result.CompletedSynchronously)
                {
                    this.HandleCloseComplete(result); 
                    this.Complete(true);
                } 
            } 

            static void OnCloseComplete(IAsyncResult result) 
            {
                if (result.CompletedSynchronously)
                    return;
 
                CloseAsyncResult thisPtr = (CloseAsyncResult)result.AsyncState;
 
                using (ServiceModelActivity.BoundOperation(thisPtr.CallbackActivity)) 
                {
                    Exception exception = null; 

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

                        exception = e;

                        if (DiagnosticUtility.ShouldTraceWarning) 
                        {
                            DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, 
                                TraceCode.CommunicationObjectCloseFailed, 
                                SR.GetString(SR.TraceCodeCommunicationObjectCloseFailed,
                                thisPtr.communicationObject.GetCommunicationObjectType().ToString()), 
                                null, null, thisPtr);
                        }

                        thisPtr.communicationObject.Abort(); 
                    }
 
                    thisPtr.Complete(false, exception); 
                }
            } 

            void HandleCloseComplete(IAsyncResult result)
            {
                this.communicationObject.OnEndClose(result); 
                this.communicationObject.OnClosed();
                if (!this.communicationObject.onClosedCalled) 
                { 
                    throw TraceUtility.ThrowHelperError(
                        this.communicationObject.CreateBaseClassMethodNotCalledException("OnClosed"), 
                        Guid.Empty, this.communicationObject);
                }
            }
 
            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