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

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

namespace System.ServiceModel.Channels 
{
    using System.Runtime.InteropServices; 
    using System.ServiceModel; 
    using System.Threading;
    using System.Transactions; 
    using SR=System.ServiceModel.SR;

    sealed class MsmqInputSessionChannel : InputChannel, IInputSessionChannel
    { 
        IInputSession session;
        Transaction associatedTx; 
 
        public MsmqInputSessionChannel(MsmqInputSessionChannelListener listener, Transaction associatedTx)
            : base(listener, new EndpointAddress(listener.Uri)) 
        {
            this.session = new InputSession();
            this.associatedTx = associatedTx;
            this.associatedTx.EnlistVolatile(new TransactionEnlistment(this, this.associatedTx), EnlistmentOptions.None); 
        }
 
        public IInputSession Session 
        {
            get { return this.session; } 
        }

        public override Message Receive()
        { 
            return this.Receive(this.DefaultReceiveTimeout);
        } 
 
        public override Message Receive(TimeSpan timeout)
        { 
            return InputChannel.HelpReceive(this, timeout);
        }

        public override IAsyncResult BeginReceive(AsyncCallback callback, object state) 
        {
            return this.BeginReceive(this.DefaultReceiveTimeout, callback, state); 
        } 

        public override IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state) 
        {
            return InputChannel.HelpBeginReceive(this, timeout, callback, state);
        }
 
        public override bool TryReceive(TimeSpan timeout, out Message message)
        { 
            ThrowIfFaulted(); 
            if (CommunicationState.Closed == this.State || CommunicationState.Closing == this.State)
            { 
                message = null;
                return true;
            }
            VerifyTransaction(); 
            return base.TryReceive(timeout, out message);
        } 
 
        public override IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
        { 
            ThrowIfFaulted();
            if (CommunicationState.Closed == this.State || CommunicationState.Closing == this.State)
            {
                return new TypedCompletedAsyncResult(true, null, callback, state); 
            }
            VerifyTransaction(); 
            return base.BeginTryReceive(timeout, callback, state); 
        }
 
        public override bool EndTryReceive(IAsyncResult result, out Message message)
        {
            TypedCompletedAsyncResult completedResult = result as TypedCompletedAsyncResult;
            if (null != completedResult) 
                return TypedCompletedAsyncResult.End(result, out message);
            else 
                return base.EndTryReceive(result, out message); 
        }
 
        public void FaultChannel()
        {
            this.Fault();
        } 

        void OnCloseCore(bool isAborting) 
        { 
            if (isAborting)
            { 
                RollbackTransaction();
            }
            else
            { 
                VerifyTransaction();
                if (this.InternalPendingItems > 0) 
                { 
                    RollbackTransaction();
                    this.Fault(); 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MsmqSessionMessagesNotConsumed)));
                }
            }
        } 

        protected override void OnAbort() 
        { 
            OnCloseCore(true);
            base.OnAbort(); 
        }

        protected override void OnClose(TimeSpan timeout)
        { 
            OnCloseCore(false);
            base.OnClose(timeout); 
        } 

        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 
        {
            OnCloseCore(false);
            return base.OnBeginClose(timeout, callback, state);
        } 

        void RollbackTransaction() 
        { 
            try
            { 
                if (TransactionStatus.Active == this.associatedTx.TransactionInformation.Status)
                    this.associatedTx.Rollback();
            }
            catch (TransactionAbortedException ex) 
            {
                MsmqDiagnostics.ExpectedException(ex); 
            } 
            catch (ObjectDisposedException ex)
            { 
                MsmqDiagnostics.ExpectedException(ex);
            }
        }
 
        void VerifyTransaction()
        { 
            if (this.InternalPendingItems > 0) 
            {
                if (this.associatedTx != Transaction.Current) 
                {
                    RollbackTransaction();
                    this.Fault();
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new InvalidOperationException(SR.GetString(SR.MsmqSameTransactionExpected))); 
                }
 
                if (TransactionStatus.Active != Transaction.Current.TransactionInformation.Status) 
                {
                    RollbackTransaction(); 
                    this.Fault();
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new InvalidOperationException(SR.GetString(SR.MsmqTransactionNotActive)));
                }
            } 
        }
 
        class InputSession : IInputSession 
        {
            string id = "uuid://session-gram/" + Guid.NewGuid().ToString(); 

            public string Id
            {
                get { return this.id; } 
            }
        } 
 
        class TransactionEnlistment : IEnlistmentNotification
        { 
            MsmqInputSessionChannel channel;
            Transaction transaction;

            public TransactionEnlistment(MsmqInputSessionChannel channel, Transaction transaction) 
            {
                this.channel = channel; 
                this.transaction = transaction; 
            }
 
            public void Prepare(PreparingEnlistment preparingEnlistment)
            {
                // Abort if this happens before all messges are consumed
                if (this.channel.State == CommunicationState.Opened && this.channel.InternalPendingItems > 0) 
                {
                    Exception e = DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MsmqSessionChannelsMustBeClosed))); 
                    preparingEnlistment.ForceRollback(e); 
                    this.channel.Fault();
                } 
                else
                {
                    preparingEnlistment.Done();
                } 
            }
 
            public void Commit(Enlistment enlistment) 
            {
                enlistment.Done(); 
            }

            public void Rollback(Enlistment enlistment)
            { 
                channel.Fault();
                enlistment.Done(); 
            } 

            public void InDoubt(Enlistment enlistment) 
            {
                enlistment.Done();
            }
        } 
    }
} 

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