예제 #1
0
        public MessageRpc(Message message, OperationContext operationContext, bool impersonationRequired)
        {
            Fx.Assert(message != null, "message cannot be null");
            Fx.Assert(operationContext != null, "operationContext cannot be null");

            this.originalMessage  = message;
            this.OperationContext = operationContext;

            if (Fx.Trace.IsEtwProviderEnabled)
            {
                this.eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message);
            }

            //passing in true causes this to return null if the thread is not impersonating.
            this.windowsIdentity = WindowsIdentity.GetCurrent(true);
            if (impersonationRequired && !AspNetEnvironment.Current.AspNetCompatibilityEnabled)
            {
                if (this.windowsIdentity == null || this.windowsIdentity.ImpersonationLevel != TokenImpersonationLevel.Impersonation)
                {
                    //Temporarily revert impersonation to process token to throw an exception
                    IDisposable autoRevert = null;
                    try
                    {
                        try { }
                        finally
                        {
                            autoRevert = WindowsIdentity.Impersonate(IntPtr.Zero);
                        }

                        Win32Exception errorDetail = new Win32Exception(ERROR_BAD_IMPERSONATION_LEVEL);
                        throw FxTrace.Exception.AsError(new SecurityNegotiationException(errorDetail.Message));
                    }
                    finally
                    {
                        if (autoRevert != null)
                        {
                            autoRevert.Dispose();
                        }
                    }
                }
            }

            ReceiveContext.TryGet(message, out this.receiveContext);

            this.transaction = Transaction.Current;
            if (this.transaction == null)
            {
                this.transaction = TransactionMessageProperty.TryGetTransaction(message);
            }
        }
예제 #2
0
        // The demand is not added now (in 4.5), to avoid a breaking change. To be considered in the next version.

        /*
         * [PermissionSet(SecurityAction.Demand, Unrestricted = true)] // because we call code from a non-APTCA assembly; transactions are not supported in partial trust, so customers should not be broken by this demand
         */
        public static Transaction GetMessageTransaction(Message message)
        {
            ServiceConfig serviceConfig = new ServiceConfig();

            serviceConfig.Transaction = TransactionOption.Disabled;
            ServiceDomain.Enter(serviceConfig);
            try
            {
                return(TransactionMessageProperty.TryGetTransaction(message));
            }
            finally
            {
                ServiceDomain.Leave();
            }
        }
        public static Transaction GetMessageTransaction(Message message)
        {
            Transaction   transaction;
            ServiceConfig cfg = new ServiceConfig {
                Transaction = TransactionOption.Disabled
            };

            ServiceDomain.Enter(cfg);
            try
            {
                transaction = TransactionMessageProperty.TryGetTransaction(message);
            }
            finally
            {
                ServiceDomain.Leave();
            }
            return(transaction);
        }
예제 #4
0
                    public CallbackAsyncResult(IDuplexRouterCallback callbackInstance, Message message, AsyncCallback callback, object state)
                        : base(callback, state)
                    {
                        this.callbackInstance = callbackInstance;

                        IAsyncResult result;

                        using (this.PrepareTransactionalCall(TransactionMessageProperty.TryGetTransaction(message)))
                        {
                            result = this.callbackInstance.BeginProcessMessage(message,
                                                                               this.PrepareAsyncCompletion(processCallback), this);
                        }

                        if (this.SyncContinue(result))
                        {
                            this.Complete(true);
                        }
                    }
예제 #5
0
        internal MessageRpc(RequestContext requestContext, Message request, DispatchOperationRuntime operation,
                            ServiceChannel channel, ServiceHostBase host, ChannelHandler channelHandler, bool cleanThread,
                            OperationContext operationContext, InstanceContext instanceContext, EventTraceActivity eventTraceActivity)
        {
            Fx.Assert((operationContext != null), "System.ServiceModel.Dispatcher.MessageRpc.MessageRpc(), operationContext == null");
            Fx.Assert(channelHandler != null, "System.ServiceModel.Dispatcher.MessageRpc.MessageRpc(), channelHandler == null");

            this.Activity                   = null;
            this.EventTraceActivity         = eventTraceActivity;
            this.AsyncResult                = null;
            this.CanSendReply               = true;
            this.Channel                    = channel;
            this.channelHandler             = channelHandler;
            this.Correlation                = EmptyArray.Allocate(operation.Parent.CorrelationCount);
            this.CorrelationCallback        = null;
            this.DidDeserializeRequestBody  = false;
            this.TransactionMessageProperty = null;
            this.TransactedBatchContext     = null;
            this.Error              = null;
            this.ErrorProcessor     = null;
            this.FaultInfo          = new ErrorHandlerFaultInfo(request.Version.Addressing.DefaultFaultAction);
            this.HasSecurityContext = false;
            this.Host     = host;
            this.Instance = null;
            this.MessageRpcOwnsInstanceContextThrottle = false;
            this.NextProcessor        = null;
            this.NotUnderstoodHeaders = null;
            this.Operation            = operation;
            this.OperationContext     = operationContext;
            this.paused                     = false;
            this.ParametersDisposed         = false;
            this.ReceiveContext             = null;
            this.Request                    = request;
            this.RequestContext             = requestContext;
            this.RequestContextThrewOnReply = false;
            this.SuccessfullySendReply      = false;
            this.RequestVersion             = request.Version;
            this.Reply = null;
            this.ReplyTimeoutHelper              = new TimeoutHelper();
            this.SecurityContext                 = null;
            this.InstanceContext                 = instanceContext;
            this.SuccessfullyBoundInstance       = false;
            this.SuccessfullyIncrementedActivity = false;
            this.SuccessfullyLockedInstance      = false;
            this.switchedThreads                 = !cleanThread;
            this.transaction                = null;
            this.InputParameters            = null;
            this.OutputParameters           = null;
            this.ReturnParameter            = null;
            this.isInstanceContextSingleton = InstanceContextProviderBase.IsProviderSingleton(this.Channel.DispatchRuntime.InstanceContextProvider);
            this.invokeContinueGate         = null;

            if (!operation.IsOneWay && !operation.Parent.ManualAddressing)
            {
                this.RequestID   = request.Headers.MessageId;
                this.ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo(request);
            }
            else
            {
                this.RequestID   = null;
                this.ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo();
            }

            this.HostingProperty = AspNetEnvironment.Current.GetHostingProperty(request, true);

            if (DiagnosticUtility.ShouldUseActivity)
            {
                this.Activity = TraceUtility.ExtractActivity(this.Request);
            }

            if (DiagnosticUtility.ShouldUseActivity || TraceUtility.ShouldPropagateActivity)
            {
                this.ResponseActivityId = ActivityIdHeader.ExtractActivityId(this.Request);
            }
            else
            {
                this.ResponseActivityId = Guid.Empty;
            }

            this.InvokeNotification = new MessageRpcInvokeNotification(this.Activity, this.channelHandler);

            if (this.EventTraceActivity == null && FxTrace.Trace.IsEnd2EndActivityTracingEnabled)
            {
                if (this.Request != null)
                {
                    this.EventTraceActivity = EventTraceActivityHelper.TryExtractActivity(this.Request, true);
                }
            }
        }
예제 #6
0
        internal void ResolveTransaction(ref MessageRpc rpc)
        {
            InstanceContext context;

            if (rpc.Operation.HasDefaultUnhandledActionInvoker)
            {
                return;
            }
            Transaction transactionForInstance = null;

            if (rpc.Operation.IsInsideTransactedReceiveScope)
            {
                IInstanceTransaction invoker = rpc.Operation.Invoker as IInstanceTransaction;
                if (invoker != null)
                {
                    transactionForInstance = invoker.GetTransactionForInstance(rpc.OperationContext);
                }
                if ((transactionForInstance != null) && DiagnosticUtility.ShouldTraceInformation)
                {
                    TraceUtility.TraceEvent(TraceEventType.Information, 0xe000f, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredUsingExistingTransaction", new object[] { transactionForInstance.TransactionInformation.LocalIdentifier, rpc.Operation.Name }));
                }
            }
            else
            {
                transactionForInstance = this.GetInstanceContextTransaction(ref rpc);
            }
            Transaction transaction3 = null;

            try
            {
                transaction3 = TransactionMessageProperty.TryGetTransaction(rpc.Request);
            }
            catch (TransactionException exception)
            {
                DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Error);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("SFxTransactionUnmarshalFailed", new object[] { exception.Message }), "TransactionUnmarshalingFailed", false));
            }
            if (rpc.Operation.TransactionRequired)
            {
                if (transaction3 == null)
                {
                    goto Label_0256;
                }
                if (this.isTransactedReceiveChannelDispatcher)
                {
                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        TraceUtility.TraceEvent(TraceEventType.Information, 0xe0001, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredIsTransactedTransport", new object[] { transaction3.TransactionInformation.LocalIdentifier, rpc.Operation.Name }));
                    }
                    goto Label_0256;
                }
                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    TraceUtility.TraceEvent(TraceEventType.Information, 0xe0002, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredIsTransactionFlow", new object[] { transaction3.TransactionInformation.LocalIdentifier, rpc.Operation.Name }));
                }
                if (PerformanceCounters.PerformanceCountersEnabled)
                {
                    PerformanceCounters.TxFlowed(PerformanceCounters.GetEndpointDispatcher(), rpc.Operation.Name);
                }
                bool flag = false;
                if (rpc.Operation.IsInsideTransactedReceiveScope)
                {
                    flag = transaction3.Equals(transactionForInstance);
                }
                else
                {
                    flag = transaction3 == transactionForInstance;
                }
                if (flag)
                {
                    goto Label_0256;
                }
                try
                {
                    transaction3 = transaction3.DependentClone(DependentCloneOption.RollbackIfNotComplete);
                    goto Label_0256;
                }
                catch (TransactionException exception2)
                {
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(exception2, TraceEventType.Error);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("SFxTransactionAsyncAborted"), "TransactionAborted", true));
                }
            }
            if ((transaction3 != null) && this.isTransactedReceiveChannelDispatcher)
            {
                try
                {
                    if (rpc.TransactedBatchContext != null)
                    {
                        rpc.TransactedBatchContext.ForceCommit();
                        rpc.TransactedBatchContext = null;
                    }
                    else
                    {
                        TransactionInstanceContextFacet.Complete(transaction3, null);
                    }
                }
                finally
                {
                    transaction3.Dispose();
                    transaction3 = null;
                }
            }
Label_0256:
            context = rpc.InstanceContext;
            if (context.Transaction.ShouldReleaseInstance && !this.isConcurrent)
            {
                if (context.Behavior.ReleaseServiceInstanceOnTransactionComplete)
                {
                    context.ReleaseServiceInstance();
                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        TraceUtility.TraceEvent(TraceEventType.Information, 0xe000c, System.ServiceModel.SR.GetString("TraceCodeTxReleaseServiceInstanceOnCompletion", new object[] { transactionForInstance.TransactionInformation.LocalIdentifier }));
                    }
                }
                context.Transaction.ShouldReleaseInstance = false;
                if ((transaction3 == null) || (transaction3 == transactionForInstance))
                {
                    rpc.Transaction.Current = transactionForInstance;
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("SFxTransactionAsyncAborted"), "TransactionAborted", true));
                }
                transactionForInstance = null;
            }
            if (rpc.Operation.TransactionRequired)
            {
                if (transaction3 == null)
                {
                    if (transactionForInstance != null)
                    {
                        transaction3 = transactionForInstance;
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            TraceUtility.TraceEvent(TraceEventType.Information, 0xe0003, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredIsAttachedTransaction", new object[] { transaction3.TransactionInformation.LocalIdentifier, rpc.Operation.Name }));
                        }
                    }
                    else
                    {
                        transaction3 = CreateTransaction(this.isolation, this.timeout);
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            TraceUtility.TraceEvent(TraceEventType.Information, 0xe0004, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredIsCreateNewTransaction", new object[] { transaction3.TransactionInformation.LocalIdentifier, rpc.Operation.Name }));
                        }
                    }
                }
                if ((this.isolation != IsolationLevel.Unspecified) && (transaction3.IsolationLevel != this.isolation))
                {
                    throw TraceUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("IsolationLevelMismatch2", new object[] { transaction3.IsolationLevel, this.isolation }), "TransactionIsolationLevelMismatch", false), rpc.Request);
                }
                rpc.Transaction.Current = transaction3;
                rpc.InstanceContext.Transaction.AddReference(ref rpc, rpc.Transaction.Current, true);
                try
                {
                    rpc.Transaction.Clone = transaction3.Clone();
                    if (rpc.Operation.IsInsideTransactedReceiveScope)
                    {
                        rpc.Transaction.CreateDependentClone();
                    }
                }
                catch (ObjectDisposedException exception3)
                {
                    DiagnosticUtility.ExceptionUtility.TraceHandledException(exception3, TraceEventType.Error);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("SFxTransactionAsyncAborted"), "TransactionAborted", true));
                }
                rpc.InstanceContext.Transaction.AddReference(ref rpc, rpc.Transaction.Clone, false);
                rpc.OperationContext.TransactionFacet = rpc.Transaction;
                if (!rpc.Operation.TransactionAutoComplete)
                {
                    rpc.Transaction.SetIncomplete();
                }
            }
        }
        internal void ResolveTransaction(ref MessageRpc rpc)
        {
            if (rpc.Operation.HasDefaultUnhandledActionInvoker)
            {
                // we ignore unhandled operations
                return;
            }

            Transaction contextTransaction = null;

            //If we are inside a TransactedReceiveScope in workflow, then we need to look into the PPD and not the InstanceContext
            //to get the contextTransaction
            if (rpc.Operation.IsInsideTransactedReceiveScope)
            {
                // We may want to use an existing transaction for the instance.
                IInstanceTransaction instanceTransaction = rpc.Operation.Invoker as IInstanceTransaction;
                if (instanceTransaction != null)
                {
                    contextTransaction = instanceTransaction.GetTransactionForInstance(rpc.OperationContext);
                }

                if (contextTransaction != null)
                {
                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        TraceUtility.TraceEvent(TraceEventType.Information,
                                                TraceCode.TxSourceTxScopeRequiredUsingExistingTransaction,
                                                SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredUsingExistingTransaction,
                                                             contextTransaction.TransactionInformation.LocalIdentifier,
                                                             rpc.Operation.Name)
                                                );
                    }
                }
            }
            else
            {
                contextTransaction = this.GetInstanceContextTransaction(ref rpc);
            }

            Transaction transaction = null;

            try
            {
                transaction = TransactionMessageProperty.TryGetTransaction(rpc.Request);
            }
            catch (TransactionException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(TransactionBehavior.CreateFault(SR.GetString(SR.SFxTransactionUnmarshalFailed, e.Message), FaultCodeConstants.Codes.TransactionUnmarshalingFailed, false));
            }

            if (rpc.Operation.TransactionRequired)
            {
                if (transaction != null)
                {
                    if (this.isTransactedReceiveChannelDispatcher)
                    {
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            TraceUtility.TraceEvent(TraceEventType.Information,
                                                    TraceCode.TxSourceTxScopeRequiredIsTransactedTransport,
                                                    SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredIsTransactedTransport,
                                                                 transaction.TransactionInformation.LocalIdentifier,
                                                                 rpc.Operation.Name)
                                                    );
                        }
                    }
                    else
                    {
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            TraceUtility.TraceEvent(TraceEventType.Information,
                                                    TraceCode.TxSourceTxScopeRequiredIsTransactionFlow,
                                                    SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredIsTransactionFlow,
                                                                 transaction.TransactionInformation.LocalIdentifier,
                                                                 rpc.Operation.Name)
                                                    );
                        }

                        if (PerformanceCounters.PerformanceCountersEnabled)
                        {
                            PerformanceCounters.TxFlowed(PerformanceCounters.GetEndpointDispatcher(), rpc.Operation.Name);
                        }

                        bool sameTransaction = false;
                        if (rpc.Operation.IsInsideTransactedReceiveScope)
                        {
                            sameTransaction = transaction.Equals(contextTransaction);
                        }
                        else
                        {
                            sameTransaction = transaction == contextTransaction;
                        }

                        if (!sameTransaction)
                        {
                            try
                            {
                                transaction = transaction.DependentClone(DependentCloneOption.RollbackIfNotComplete);
                            }
                            catch (TransactionException e)
                            {
                                DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(TransactionBehavior.CreateFault(SR.GetString(SR.SFxTransactionAsyncAborted), FaultCodeConstants.Codes.TransactionAborted, true));
                            }
                        }
                    }
                }
            }
            else
            {
                // We got a transaction from the ChannelHandler.
                // Transport is transacted.
                // But operation doesn't require the transaction, so no one ever will commit it.
                // Because of that we have to commit it here.
                if (transaction != null && this.isTransactedReceiveChannelDispatcher)
                {
                    try
                    {
                        if (null != rpc.TransactedBatchContext)
                        {
                            rpc.TransactedBatchContext.ForceCommit();
                            rpc.TransactedBatchContext = null;
                        }
                        else
                        {
                            TransactionInstanceContextFacet.Complete(transaction, null);
                        }
                    }
                    finally
                    {
                        transaction.Dispose();
                        transaction = null;
                    }
                }
            }

            InstanceContext context = rpc.InstanceContext;

            if (context.Transaction.ShouldReleaseInstance && !this.isConcurrent)
            {
                if (context.Behavior.ReleaseServiceInstanceOnTransactionComplete)
                {
                    context.ReleaseServiceInstance();
                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        TraceUtility.TraceEvent(TraceEventType.Information,
                                                TraceCode.TxReleaseServiceInstanceOnCompletion,
                                                SR.GetString(SR.TraceCodeTxReleaseServiceInstanceOnCompletion,
                                                             contextTransaction.TransactionInformation.LocalIdentifier)
                                                );
                    }
                }

                context.Transaction.ShouldReleaseInstance = false;

                if (transaction == null || transaction == contextTransaction)
                {
                    rpc.Transaction.Current = contextTransaction;
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(TransactionBehavior.CreateFault(SR.GetString(SR.SFxTransactionAsyncAborted), FaultCodeConstants.Codes.TransactionAborted, true));
                }
                else
                {
                    contextTransaction = null;
                }
            }

            if (rpc.Operation.TransactionRequired)
            {
                if (transaction == null)
                {
                    if (contextTransaction != null)
                    {
                        transaction = contextTransaction;
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            TraceUtility.TraceEvent(TraceEventType.Information,
                                                    TraceCode.TxSourceTxScopeRequiredIsAttachedTransaction,
                                                    SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredIsAttachedTransaction,
                                                                 transaction.TransactionInformation.LocalIdentifier,
                                                                 rpc.Operation.Name)
                                                    );
                        }
                    }
                    else
                    {
                        transaction = TransactionBehavior.CreateTransaction(this.isolation, this.timeout);
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            TraceUtility.TraceEvent(TraceEventType.Information,
                                                    TraceCode.TxSourceTxScopeRequiredIsCreateNewTransaction,
                                                    SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredIsCreateNewTransaction,
                                                                 transaction.TransactionInformation.LocalIdentifier,
                                                                 rpc.Operation.Name)
                                                    );
                        }
                    }
                }

                if ((this.isolation != IsolationLevel.Unspecified) && (transaction.IsolationLevel != this.isolation))
                {
                    throw TraceUtility.ThrowHelperError(TransactionBehavior.CreateFault
                                                            (SR.GetString(SR.IsolationLevelMismatch2, transaction.IsolationLevel, this.isolation), FaultCodeConstants.Codes.TransactionIsolationLevelMismatch, false), rpc.Request);
                }

                rpc.Transaction.Current = transaction;
                rpc.InstanceContext.Transaction.AddReference(ref rpc, rpc.Transaction.Current, true);

                try
                {
                    rpc.Transaction.Clone = transaction.Clone();
                    if (rpc.Operation.IsInsideTransactedReceiveScope)
                    {
                        //It is because we want to synchronize the dispatcher processing of messages with the commit
                        //processing that is started by the completion of a TransactedReceiveScope. We need to make sure
                        //that all the dispatcher processing is done and we can do that by creating a blocking dependent clone and only
                        //completing it after all of the message processing is done for a given TransactionRpcFacet
                        rpc.Transaction.CreateDependentClone();
                    }
                }
                catch (ObjectDisposedException e)//transaction may be async aborted
                {
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Error);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(TransactionBehavior.CreateFault(SR.GetString(SR.SFxTransactionAsyncAborted), FaultCodeConstants.Codes.TransactionAborted, true));
                }

                rpc.InstanceContext.Transaction.AddReference(ref rpc, rpc.Transaction.Clone, false);

                rpc.OperationContext.TransactionFacet = rpc.Transaction;

                if (!rpc.Operation.TransactionAutoComplete)
                {
                    rpc.Transaction.SetIncomplete();
                }
            }
        }
        Message EndReceive(Socket listenSocket, IAsyncResult result)
        {
            // if we've started the shutdown process, then we've disposed
            // the socket and calls to socket.EndReceive will throw
            if (base.State != CommunicationState.Opened)
            {
                return(null);
            }

            byte[] buffer = ((SocketReceiveState)result.AsyncState).Buffer;

            Message message = null;

            try
            {
                int count = 0;

                lock (ThisLock)
                {
                    // if we've started the shutdown process, socket is disposed
                    // and calls to socket.EndReceive will throw
                    if (base.State == CommunicationState.Opened)
                    {
                        EndPoint dummy = CreateDummyEndPoint(listenSocket);
                        count = listenSocket.EndReceiveFrom(result, ref dummy);
                    }
                }

                if (count > 0)
                {
                    ArraySegment <byte> msg;
                    Transaction         transaction;

                    // read the transaction and message
                    TransactionMessageBuffer.ReadTransactionMessageBuffer(buffer, count, out transaction, out msg);

                    try
                    {
                        message = MessageEncoderFactory.Encoder.ReadMessage(msg, bufferManager);
                    }
                    catch (XmlException xmlException)
                    {
                        throw new ProtocolException(
                                  "There is a problem with the XML that was received from the network. See inner exception for more details.",
                                  xmlException);
                    }

                    if (transaction != null)
                    {
                        // This is where we set the transaction on the message in order to be picked up by
                        // the dispatcher, and used to call the service operation. We use the
                        // System.ServiceModel.Channels.TransactionMessageProperty provided by the WCF framework.
                        TransactionMessageProperty.Set(transaction, message);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("Error in completing the async receive via EndReceiveFrom method.");
                Debug.WriteLine(e.ToString());
            }
            finally
            {
                if (message == null)
                {
                    this.bufferManager.ReturnBuffer(buffer);
                    buffer = null;
                }
            }

            return(message);
        }