ProcessRequestAsyncResult.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.ServiceModel.Routing / System / ServiceModel / Routing / ProcessRequestAsyncResult.cs / 1305376 / ProcessRequestAsyncResult.cs

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

namespace System.ServiceModel.Routing 
{
    using System; 
    using System.Configuration; 
    using System.Runtime;
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Dispatcher;
    using System.Threading;
    using System.Transactions;
    //using System.Security.Principal; 

    class ProcessRequestAsyncResult : AsyncResult 
    { 
        static AsyncCompletion operationCallback = new AsyncCompletion(OperationCallback);
        RoutingService service; 
        IRoutingClient currentClient;
        MessageRpc messageRpc;
        Message replyMessage;
        bool allCompletedSync; 
        bool abortedRetry;
 
        public ProcessRequestAsyncResult(RoutingService service, Message message, AsyncCallback callback, object state) 
            : base(callback, state)
        { 
            this.allCompletedSync = true;
            this.service = service;
            this.messageRpc = new MessageRpc(message, OperationContext.Current, service.ChannelExtension.ImpersonationRequired);
            if (TD.RoutingServiceProcessingMessageIsEnabled()) 
            {
                TD.RoutingServiceProcessingMessage(this.messageRpc.UniqueID, message.Headers.Action, this.messageRpc.OperationContext.EndpointDispatcher.EndpointAddress.Uri.ToString(), messageRpc.Transaction != null ? "True" : "False"); 
            } 

            try 
            {
                EndpointNameMessageFilter.Set(this.messageRpc.Message.Properties, service.ChannelExtension.EndpointName);
                this.messageRpc.RouteToSingleEndpoint(this.service.RoutingConfig);
            } 
            catch (MultipleFilterMatchesException matchesException)
            { 
                // Wrap this exception with one that is more meaningful to users of RoutingService: 
                throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR.ReqReplyMulticastNotSupported(this.messageRpc.OperationContext.Channel.LocalAddress), matchesException));
            } 

            while (this.StartProcessing())
            {
            } 
        }
 
        bool StartProcessing() 
        {
            bool callAgain = false; 
            SendOperation sendOperation = this.messageRpc.Operations[0];
            this.currentClient = this.service.GetOrCreateClient(sendOperation.CurrentEndpoint, this.messageRpc.Impersonating);

            if (TD.RoutingServiceTransmittingMessageIsEnabled()) 
            {
                TD.RoutingServiceTransmittingMessage(this.messageRpc.UniqueID, "0", this.currentClient.Key.ToString()); 
            } 

            try 
            {
                if (messageRpc.Transaction != null && sendOperation.HasAlternate)
                {
                    throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR.ErrorHandlingNotSupportedReqReplyTxn(this.messageRpc.OperationContext.Channel.LocalAddress))); 
                }
 
                Message message; 
                if (sendOperation.HasAlternate)
                { 
                    message = messageRpc.CreateBuffer().CreateMessage();
                }
                else
                { 
                    message = messageRpc.Message;
                } 
                sendOperation.PrepareMessage(message); 

                IAsyncResult result = null; 
                using (this.PrepareTransactionalCall(messageRpc.Transaction))
                {
                    IDisposable impersonationContext = null;
                    try 
                    {
                        //Perform the assignment in a finally block so it won't be interrupted asynchronously 
                        try { } 
                        finally
                        { 
                            impersonationContext = messageRpc.PrepareCall();
                        }
                        result = this.currentClient.BeginOperation(message, messageRpc.Transaction, this.PrepareAsyncCompletion(operationCallback), this);
                    } 
                    finally
                    { 
                        if (impersonationContext != null) 
                        {
                            impersonationContext.Dispose(); 
                        }
                    }
                }
 
                if (this.CheckSyncContinue(result))
                { 
                    if (this.OperationComplete(result)) 
                    {
                        this.Complete(this.allCompletedSync); 
                    }
                    else
                    {
                        callAgain = true; 
                    }
                } 
            } 
            catch (Exception exception)
            { 
                if (Fx.IsFatal(exception))
                {
                    throw;
                } 

                if (!this.HandleClientOperationFailure(exception)) 
                { 
                    throw;
                } 
                callAgain = true;
            }
            return callAgain;
        } 

        static bool OperationCallback(IAsyncResult result) 
        { 
            ProcessRequestAsyncResult thisPtr = (ProcessRequestAsyncResult)result.AsyncState;
            FxTrace.Trace.SetAndTraceTransfer(thisPtr.service.ChannelExtension.ActivityID, true); 
            thisPtr.allCompletedSync = false;

            try
            { 
                if (thisPtr.OperationComplete(result))
                { 
                    return true; 
                }
            } 
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                { 
                    throw;
                } 
 
                if (!thisPtr.HandleClientOperationFailure(exception))
                { 
                    throw;
                }
            }
 
            while (thisPtr.StartProcessing())
            { 
            } 

            return false; 
        }

        // Returns true if we're all done and can complete this AsyncResult now
        bool OperationComplete(IAsyncResult result) 
        {
            bool completeSelf = false; 
            Message responseMsg = this.currentClient.EndOperation(result); 

            if (TD.RoutingServiceTransmitSucceededIsEnabled()) 
            {
                TD.RoutingServiceTransmitSucceeded(this.messageRpc.UniqueID, "0", this.currentClient.Key.ToString());
            }
 
            if (responseMsg == null || !responseMsg.IsFault)
            { 
                if (TD.RoutingServiceSendingResponseIsEnabled()) 
                {
                    string action = (responseMsg != null) ? responseMsg.Headers.Action : string.Empty; 
                    TD.RoutingServiceSendingResponse(action);
                }
            }
            else 
            {
                if (TD.RoutingServiceSendingFaultResponseIsEnabled()) { TD.RoutingServiceSendingFaultResponse(responseMsg.Headers.Action); } 
            } 
            this.replyMessage = responseMsg;
            completeSelf = true; 

            if (TD.RoutingServiceCompletingTwoWayIsEnabled()) { TD.RoutingServiceCompletingTwoWay(null); }
            return completeSelf;
        } 

        internal static Message End(IAsyncResult result) 
        { 
            ProcessRequestAsyncResult processRequest = AsyncResult.End>(result);
            return processRequest.replyMessage; 
        }

        bool HandleClientOperationFailure(Exception exception)
        { 
            SendOperation sendOperation = this.messageRpc.Operations[0];
            if (TD.RoutingServiceTransmitFailedIsEnabled()) { TD.RoutingServiceTransmitFailed(sendOperation.CurrentEndpoint.ToString(), exception); } 
 
            if (!(exception is CommunicationException || exception is TimeoutException))
            { 
                //We only move to backup for CommunicationExceptions and TimeoutExceptions
                return false;
            }
 
            if ((exception is CommunicationObjectAbortedException || exception is CommunicationObjectFaultedException) &&
                !this.service.ChannelExtension.HasSession) 
            { 
                // Messages on a non sessionful channel share outbound connections and can
                // fail due to other messages failing on the same channel 
                if (messageRpc.Transaction == null && !this.abortedRetry)
                {
                    //No session and non transactional, retry the message 1 time (before moving to backup)
                    this.abortedRetry = true; 
                    return true;
                } 
            } 

            if (sendOperation.TryMoveToAlternate(exception)) 
            {
                if (TD.RoutingServiceMovedToBackupIsEnabled())
                {
                    TD.RoutingServiceMovedToBackup(messageRpc.UniqueID, "0", sendOperation.CurrentEndpoint.ToString()); 
                }
                return true; 
            } 
            return false;
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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