System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke C# (CSharp) Method

InternalInvoke() private method

private InternalInvoke ( IMethodCallMessage reqMcmMsg, bool useDispatchMessage, int callType ) : IMessage
reqMcmMsg IMethodCallMessage
useDispatchMessage bool
callType int
return IMessage
        internal virtual IMessage InternalInvoke(
            IMethodCallMessage reqMcmMsg, bool useDispatchMessage, int callType)
        {
            Message reqMsg = reqMcmMsg as Message;            
            if ((reqMsg == null) && (callType != Message.Sync))
            {
                // Only the synchronous call type is supported for messages that
                //   aren't of type Message.               
                throw new RemotingException(
                    Environment.GetResourceString("Remoting_Proxy_InvalidCallType"));
            }
        
            IMessage retMsg = null;
            Thread currentThread = Thread.CurrentThread;

            // pick up call context from the thread
            LogicalCallContext cctx = currentThread.GetLogicalCallContext();

            Identity idObj = IdentityObject;
            ServerIdentity serverID = idObj as ServerIdentity;
            if ((null != serverID) && idObj.IsFullyDisconnected())
            {
                throw new ArgumentException(
                   String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_ServerObjectNotFound"), reqMcmMsg.Uri));
            }

            // Short-circuit calls to Object::GetType and Object::GetHashCode
            MethodBase mb = reqMcmMsg.MethodBase;
            if(_getTypeMethod == mb)
            {
                // Time to load the true type of the remote object....
                Type t = GetProxiedType();
                return new ReturnMessage(t, null, 0, cctx, reqMcmMsg);
            }

            if (_getHashCodeMethod == mb)
            {
                int hashCode = idObj.GetHashCode();
                return new ReturnMessage(hashCode, null, 0, cctx, reqMcmMsg);
            }

            // check for channel sink
            if (idObj.ChannelSink == null)
            {
                IMessageSink chnlSink = null;
                IMessageSink envoySink = null;
                // If channelSink is null try to Create them again
                // the objref should be correctly fixed up at this point
                if(!idObj.ObjectRef.IsObjRefLite())
                {
                    RemotingServices.CreateEnvoyAndChannelSinks(null, idObj.ObjectRef, out chnlSink, out envoySink);
                }
                else
                {
                    RemotingServices.CreateEnvoyAndChannelSinks(idObj.ObjURI, null, out chnlSink, out envoySink);
                }
                // Set the envoy and channel sinks in a thread safe manner
                RemotingServices.SetEnvoyAndChannelSinks(idObj, chnlSink, envoySink);

                // If the channel sink is still null then throw
                if(idObj.ChannelSink == null)
                {
                    throw new RemotingException(
                        Environment.GetResourceString("Remoting_Proxy_NoChannelSink"));
                }
            }

            // Set the identity in the message object
            IInternalMessage iim = (IInternalMessage)reqMcmMsg;
            iim.IdentityObject = idObj;

            if (null != serverID)
            {
                Message.DebugOut("Setting serveridentity on message \n");
                iim.ServerIdentityObject = serverID;
                    
            }
            else
            {
                // We need to set the URI only for identities that 
                // are not the server identities. The uri is used to
                // dispatch methods for objects outside the appdomain.
                // Inside the appdomain (xcontext case) we dispatch 
                // by getting the server object from the server identity.
               iim.SetURI(idObj.URI);
            }       

            Message.DebugOut("InternalInvoke. Dispatching based on class type\n");
            AsyncResult ar = null;
            switch (callType)
            {
            case Message.Sync:
                Message.DebugOut("RemotingProxy.Invoke Call: SyncProcessMsg\n");
                BCLDebug.Assert(!useDispatchMessage,"!useDispatchMessage");                
                bool bSkipContextChain = false;
                Context currentContext = currentThread.GetCurrentContextInternal();
                IMessageSink nextSink = idObj.EnvoyChain;

                // if we are in the default context, there can be no 
                // client context chain, so we can skip the intermediate 
                // calls if there are no envoy sinks

                if (currentContext.IsDefaultContext)
                {
                    if (nextSink is EnvoyTerminatorSink)
                    {
                        bSkipContextChain = true;

                        // jump directly to the channel sink
                        nextSink = idObj.ChannelSink;
                    }
                }

                retMsg = CallProcessMessage(nextSink,
                                            reqMcmMsg, 
                                            idObj.ProxySideDynamicSinks,
                                            currentThread,
                                            currentContext,
                                            bSkipContextChain);

                break;

            case Message.BeginAsync:
            case Message.BeginAsync | Message.OneWay:                                        
                // For async calls we clone the call context from the thread
                // This is a limited clone (we dont deep copy the user data)
                cctx = (LogicalCallContext) cctx.Clone(); 
                iim.SetCallContext(cctx);  
                
                ar = new AsyncResult(reqMsg);
              
                InternalInvokeAsync(ar, reqMsg, useDispatchMessage, callType);

                Message.DebugOut("Propagate out params for BeginAsync\n");
                retMsg = new ReturnMessage(ar, null, 0, null/*cctx*/, reqMsg);
                break;

            case Message.OneWay:
                // For async calls we clone the call context from the thread
                // This is a limited clone (we dont deep copy the user data)
                cctx = (LogicalCallContext) cctx.Clone();
                iim.SetCallContext(cctx);
                InternalInvokeAsync(null, reqMsg, useDispatchMessage, callType);
                retMsg = new ReturnMessage(null, null, 0, null/*cctx*/, reqMcmMsg);
                break;

            case (Message.EndAsync | Message.OneWay):
                retMsg = new ReturnMessage(null, null, 0, null/*cctx*/, reqMcmMsg);
                break;

            case Message.EndAsync:
                // For endAsync, we merge back the returned callContext
                // into the thread's callContext
                retMsg = RealProxy.EndInvokeHelper(reqMsg, true);
                break;
            }
            
            return retMsg;
        }

Usage Example

Beispiel #1
0
        private static void Invoke(object NotUsed, ref MessageData msgData)
        {
            Message reqMcmMsg = new Message();

            reqMcmMsg.InitFields(msgData);
            Delegate thisPtr = reqMcmMsg.GetThisPtr() as Delegate;

            if (thisPtr == null)
            {
                throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
            }
            RemotingProxy realProxy = (RemotingProxy)RemotingServices.GetRealProxy(thisPtr.Target);

            if (realProxy != null)
            {
                realProxy.InternalInvoke(reqMcmMsg, true, reqMcmMsg.GetCallType());
            }
            else
            {
                int callType = reqMcmMsg.GetCallType();
                switch (callType)
                {
                case 1:
                case 9:
                {
                    reqMcmMsg.Properties[Message.CallContextKey] = CallContext.GetLogicalCallContext().Clone();
                    AsyncResult          retVal = new AsyncResult(reqMcmMsg);
                    AgileAsyncWorkerItem state  = new AgileAsyncWorkerItem(reqMcmMsg, ((callType & 8) != 0) ? null : retVal, thisPtr.Target);
                    ThreadPool.QueueUserWorkItem(new WaitCallback(AgileAsyncWorkerItem.ThreadPoolCallBack), state);
                    if ((callType & 8) != 0)
                    {
                        retVal.SyncProcessMessage(null);
                    }
                    reqMcmMsg.PropagateOutParameters(null, retVal);
                    break;
                }

                case 2:
                    RealProxy.EndInvokeHelper(reqMcmMsg, false);
                    return;

                case 10:
                    break;

                default:
                    return;
                }
            }
        }
All Usage Examples Of System.Runtime.Remoting.Proxies.RemotingProxy::InternalInvoke