public static void CreateIfRequired(ImmutableDispatchRuntime dispatchRuntime, ref MessageRpc messageRpc)
 {
     if (messageRpc.Operation.ReceiveContextAcknowledgementMode != ReceiveContextAcknowledgementMode.ManualAcknowledgement)
     {
         ReceiveContext property = null;
         if (!ReceiveContext.TryGet(messageRpc.Request, out property))
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("SFxReceiveContextPropertyMissing", new object[] { typeof(ReceiveContext).Name })));
         }
         messageRpc.Request.Properties.Remove(ReceiveContext.Name);
         if ((messageRpc.Operation.ReceiveContextAcknowledgementMode == ReceiveContextAcknowledgementMode.AutoAcknowledgeOnReceive) && !messageRpc.Operation.TransactionRequired)
         {
             AcknowledgementCompleteCallbackState state = new AcknowledgementCompleteCallbackState {
                 DispatchRuntime = dispatchRuntime,
                 Rpc             = messageRpc
             };
             IAsyncResult result = new AcknowledgementCompleteAsyncResult(property, TimeSpan.MaxValue, ref messageRpc, null, handleEndComplete, state);
             if (result.CompletedSynchronously)
             {
                 AcknowledgementCompleteAsyncResult.End(result);
             }
         }
         else
         {
             messageRpc.ReceiveContext = new ReceiveContextRPCFacet(property);
         }
     }
 }
        public void Complete(ImmutableDispatchRuntime dispatchRuntime, ref MessageRpc rpc, TimeSpan timeout, Transaction transaction)
        {
            AcknowledgementCompleteCallbackState state = new AcknowledgementCompleteCallbackState {
                DispatchRuntime = dispatchRuntime,
                Rpc             = rpc
            };
            IAsyncResult result = new AcknowledgementCompleteAsyncResult(this.receiveContext, timeout, ref rpc, transaction, handleEndComplete, state);

            if (result.CompletedSynchronously)
            {
                AcknowledgementCompleteAsyncResult.End(result);
            }
        }
        //Called from ProcessMessage1
        //ManualAcknowledgementMode : No-Op.
        //Non-transacted V1 Operation : Remove RC; RC.Complete;(Will pause RPC if truly async)
        //Else : Create and Attach RCFacet to MessageRPC.
        public static void CreateIfRequired(ImmutableDispatchRuntime dispatchRuntime, ref MessageRpc messageRpc)
        {
            if (messageRpc.Operation.ReceiveContextAcknowledgementMode == ReceiveContextAcknowledgementMode.ManualAcknowledgement)
            {
                //Manual mode, user owns the acknowledgement.
                return;
            }

            //Retrieve RC from request and ensure it is removed from Message.
            ReceiveContext receiveContext = null;

            if (!ReceiveContext.TryGet(messageRpc.Request, out receiveContext))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new InvalidOperationException(
                              SR.GetString(SR.SFxReceiveContextPropertyMissing,
                                           typeof(ReceiveContext).Name)));
            }
            messageRpc.Request.Properties.Remove(ReceiveContext.Name);

            if (messageRpc.Operation.ReceiveContextAcknowledgementMode == ReceiveContextAcknowledgementMode.AutoAcknowledgeOnReceive)
            {
                if (!messageRpc.Operation.TransactionRequired)
                {
                    //Attempt to complete the ReceiveContext.
                    //Async Result Ensures RPC is paused if it goes ASYNC.
                    IAsyncResult result = new AcknowledgementCompleteAsyncResult(
                        receiveContext,
                        TimeSpan.MaxValue,
                        ref messageRpc,
                        null,
                        handleEndComplete,
                        new AcknowledgementCompleteCallbackState
                    {
                        DispatchRuntime = dispatchRuntime,
                        Rpc             = messageRpc
                    });

                    if (result.CompletedSynchronously)
                    {
                        AcknowledgementCompleteAsyncResult.End(result);
                    }
                    return;
                }
            }
            //We have to create a Facet for acknowledgement at later stage.
            messageRpc.ReceiveContext = new ReceiveContextRPCFacet(receiveContext);
        }
        //Called from ProcessMessage31.
        //Mode is TransactedOperation && !ManualAcknowledgement
        //Will pause RPC if Complete is truly Async.
        public void Complete(ImmutableDispatchRuntime dispatchRuntime, ref MessageRpc rpc, TimeSpan timeout, Transaction transaction)
        {
            Fx.Assert(transaction != null, "Cannot reach here with null transaction");
            //Async Result Ensures the RPC is paused if the request goes Async.
            IAsyncResult result = new AcknowledgementCompleteAsyncResult(
                this.receiveContext,
                timeout,
                ref rpc,
                transaction,
                handleEndComplete,
                new AcknowledgementCompleteCallbackState
            {
                DispatchRuntime = dispatchRuntime,
                Rpc             = rpc
            });

            if (result.CompletedSynchronously)
            {
                AcknowledgementCompleteAsyncResult.End(result);
            }
        }
 private static void HandleEndComplete(IAsyncResult result)
 {
     if (!result.CompletedSynchronously)
     {
         try
         {
             AcknowledgementCompleteAsyncResult.End(result);
         }
         catch (Exception exception)
         {
             if (Fx.IsFatal(exception))
             {
                 throw;
             }
             AcknowledgementCompleteCallbackState asyncState = (AcknowledgementCompleteCallbackState)result.AsyncState;
             MessageRpc rpc = asyncState.Rpc;
             rpc.Error = exception;
             asyncState.DispatchRuntime.ErrorBehavior.HandleError(ref rpc);
         }
     }
 }