private PropagateOutParameters ( Object OutArgs, Object retVal ) : void | ||
OutArgs | Object | |
retVal | Object | |
return | void |
[System.Security.SecurityCritical] // auto-generated internal static IMessage EndInvokeHelper(Message reqMsg, bool bProxyCase) { AsyncResult ar = reqMsg.GetAsyncResult() as AsyncResult; IMessage retMsg = null; // used for proxy case only! if (ar == null) { throw new RemotingException( Environment.GetResourceString( "Remoting_Message_BadAsyncResult")); } if (ar.AsyncDelegate != reqMsg.GetThisPtr()) { throw new InvalidOperationException(Environment.GetResourceString( "InvalidOperation_MismatchedAsyncResult")); } if (!ar.IsCompleted) { // Note: using ThreadPoolAware to detect if this is a // ThreadAffinity or Synchronization context. ar.AsyncWaitHandle.WaitOne( Int32.MaxValue, Thread.CurrentContext.IsThreadPoolAware); } lock (ar) { if (ar.EndInvokeCalled) throw new InvalidOperationException( Environment.GetResourceString( "InvalidOperation_EndInvokeCalledMultiple")); ar.EndInvokeCalled = true; IMethodReturnMessage mrm = (IMethodReturnMessage) ar.GetReplyMessage(); Contract.Assert( mrm != null, "Reply sink should ensure we have a reply message before signalling"); // For the proxy case this is handled by RealProxy if (!bProxyCase) { Exception e = mrm.Exception; if (e != null) { // throw e; throw e.PrepForRemoting(); } else { reqMsg.PropagateOutParameters( mrm.Args, mrm.ReturnValue); } } else { retMsg = mrm; } // Merge the call context back into the thread that // called EndInvoke CallContext.GetLogicalCallContext().Merge( mrm.LogicalCallContext); } // Will be non-null only for proxy case! return retMsg; } // EndInvokeHelper
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; } } }
// Invoke for case where call is in the same context as the server object // (This special static method is used for AsyncDelegate-s ... this is called // directly from the EE) private static void Invoke(Object NotUsed, ref MessageData msgData) { Message m = new Message(); m.InitFields(msgData); Object thisPtr = m.GetThisPtr(); Delegate d; if ((d = thisPtr as Delegate) != null) { RemotingProxy rp = (RemotingProxy) RemotingServices.GetRealProxy(d.Target); if (rp != null) { rp.InternalInvoke(m, true, m.GetCallType()); } else { int callType = m.GetCallType(); AsyncResult ar; switch (callType) { case Message.BeginAsync: case Message.BeginAsync | Message.OneWay: // pick up call context from the thread m.Properties[Message.CallContextKey] = CallContext.GetLogicalCallContext().Clone(); ar = new AsyncResult(m); AgileAsyncWorkerItem workItem = new AgileAsyncWorkerItem( m, ((callType & Message.OneWay) != 0) ? null : ar, d.Target); ThreadPool.QueueUserWorkItem( new WaitCallback( AgileAsyncWorkerItem.ThreadPoolCallBack), workItem); if ((callType & Message.OneWay) != 0) { ar.SyncProcessMessage(null); } m.PropagateOutParameters(null, ar); break; case (Message.EndAsync | Message.OneWay): return; case Message.EndAsync: // This will also merge back the call context // onto the thread that called EndAsync RealProxy.EndInvokeHelper(m, false); break; default: BCLDebug.Assert( false, "Should never be here. Sync delegate code for agile object ended up in remoting"); break; } } } else { // Static invoke called with incorrect this pointer ... throw new RemotingException( Environment.GetResourceString( "Remoting_Default")); } }
internal static IMessage EndInvokeHelper(Message reqMsg, bool bProxyCase) { AsyncResult asyncResult = reqMsg.GetAsyncResult() as AsyncResult; IMessage message = null; if (asyncResult == null) { throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadAsyncResult")); } if (asyncResult.AsyncDelegate != reqMsg.GetThisPtr()) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MismatchedAsyncResult")); } if (!asyncResult.IsCompleted) { asyncResult.AsyncWaitHandle.WaitOne(0x7fffffff, Thread.CurrentContext.IsThreadPoolAware); } lock (asyncResult) { if (asyncResult.EndInvokeCalled) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EndInvokeCalledMultiple")); } asyncResult.EndInvokeCalled = true; IMethodReturnMessage replyMessage = (IMethodReturnMessage) asyncResult.GetReplyMessage(); if (!bProxyCase) { Exception exception = replyMessage.Exception; if (exception != null) { throw exception.PrepForRemoting(); } reqMsg.PropagateOutParameters(replyMessage.Args, replyMessage.ReturnValue); } else { message = replyMessage; } CallContext.GetLogicalCallContext().Merge(replyMessage.LogicalCallContext); } return message; }