System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage C# (CSharp) Method

AsyncProcessMessage() public method

public AsyncProcessMessage ( IMessage msg, IMessageSink replySink ) : IMessageCtrl
msg IMessage
replySink IMessageSink
return IMessageCtrl
        public virtual IMessageCtrl AsyncProcessMessage(
            IMessage msg, IMessageSink replySink) 
        { 
            IMethodCallMessage mcMsg = (IMethodCallMessage)msg;

            IMessageCtrl retCtrl = null;
            IMessage retMessage = null;
            LogicalCallContext oldCallCtx = null;
            bool isCallContextSet = false;
            try{
                try
                {
                    LogicalCallContext callCtx =  (LogicalCallContext)
                        mcMsg.Properties[Message.CallContextKey];
                        
                    Object server = _server;

                    // validate the method base if necessary
                    VerifyIsOkToCallMethod(server, mcMsg);
                    
                    // install call context onto the thread, holding onto
                    // the one that is currently on the thread

                    oldCallCtx = CallContext.SetLogicalCallContext(callCtx);
                    isCallContextSet = true;
                    // retrieve incoming headers
                    callCtx.PropagateIncomingHeadersToCallContext(msg);

                    PreserveThreadPrincipalIfNecessary(callCtx, oldCallCtx);

                    // see if this is a server message that was dispatched asynchronously
                    ServerChannelSinkStack sinkStack = 
                        msg.Properties["__SinkStack"] as ServerChannelSinkStack;
                    if (sinkStack != null)
                        sinkStack.ServerObject = server;
                    
                    BCLDebug.Assert((server!=null)==(!_bStatic),
                                    "Invalid state in stackbuilder sink?");   
                                                
                    MethodBase mb = GetMethodBase(mcMsg);
                    Object[] outArgs = null;
                    Object ret = null;                
                    RemotingMethodCachedData methodCache = 
                        InternalRemotingServices.GetReflectionCachedData(mb);                                
                    Object[] args = Message.CoerceArgs(mcMsg, methodCache.Parameters);

                    ret = PrivateProcessMessage(mb.MethodHandle,
                                                args,
                                                server,
                                                0,
                                                false,
                                                out outArgs);
                    CopyNonByrefOutArgsFromOriginalArgs(methodCache, args, ref outArgs);
                                                           
                    if(replySink != null)
                    {     
                        // call context could be different then the one from before the call.
                        LogicalCallContext latestCallContext = CallContext.GetLogicalCallContext();
                        
                        if (latestCallContext != null)
                        {
                            // Special case Principal since if might not be serializable before returning
                            // ReturnMessage
                            latestCallContext.RemovePrincipalIfNotSerializable();
                        }
                        
                        retMessage = new ReturnMessage(
                                            ret, 
                                            outArgs, 
                                            (outArgs == null ? 0 : outArgs.Length), 
                                            latestCallContext, 
                                            mcMsg);

                        // retrieve outgoing response headers
                        latestCallContext.PropagateOutgoingHeadersToMessage(retMessage);
        
                    }
                } 
                catch (Exception e)
                {
                    if(replySink != null)
                    {
                        retMessage = new ReturnMessage(e, mcMsg);
                        ((ReturnMessage)retMessage).SetLogicalCallContext(
                                (LogicalCallContext)
                                    mcMsg.Properties[Message.CallContextKey]);

                    }
                }
                finally
                {
                    // Call the reply sink without catching the exceptions
                    // in it. In v2.0 any exceptions in the callback for example
                    // would probably bring down the process
                    replySink.SyncProcessMessage(retMessage);
                }
            }
            finally {
                // restore the call context on the thread
                if (isCallContextSet)
                    CallContext.SetLogicalCallContext(oldCallCtx);
            }

            return retCtrl; 
        } // AsyncProcessMessage

Usage Example

        [System.Security.SecurityCritical]  // auto-generated
        public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink)
        {
            IMessageCtrl msgCtrl = null;
            IMessage     errMsg  = ValidateMessage(reqMsg);

            // <

            if (errMsg != null)
            {
                if (replySink != null)
                {
                    replySink.SyncProcessMessage(errMsg);
                }
            }
            else
            {
                // Pass call on to the server object specific chain
                IMessageSink serverAsSink = _stackBuilderSink.ServerObject as IMessageSink;
                if (serverAsSink != null)
                {
                    msgCtrl = serverAsSink.AsyncProcessMessage(reqMsg, replySink);
                }
                else
                {
                    msgCtrl = _stackBuilderSink.AsyncProcessMessage(reqMsg, replySink);
                }
            }
            return(msgCtrl);
        }