MethodMessage.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 / WF / Activities / LocalService / MethodMessage.cs / 1305376 / MethodMessage.cs

                            #pragma warning disable 1634, 1691 
using System;
using System.Diagnostics;
using System.Collections;
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic; 
using System.Reflection; 
using System.Runtime.Remoting.Messaging;
using System.Workflow.Runtime; 
using System.Security.Principal;
using System.Threading;
using System.Globalization;
 
namespace System.Workflow.Activities
{ 
    internal interface IMethodResponseMessage 
    {
        void        SendResponse(ICollection outArgs); 
        void        SendException(Exception exception);
        Exception   Exception { get;}
        ICollection OutArgs { get;}
    } 

    [Serializable] 
    internal sealed class MethodMessage : IMethodMessage, IMethodResponseMessage 
    {
        [NonSerialized] 
        Type interfaceType;
        [NonSerialized]
        string methodName;
        [NonSerialized] 
        object[] args;
        [NonSerialized] 
        ManualResetEvent returnValueSignalEvent; 

        object[] clonedArgs; 
        LogicalCallContext callContext;

        ICollection outArgs;
        Exception exception; 

        [NonSerialized] 
        bool responseSet = false; 

        Guid callbackCookie; 

        [NonSerialized]
        MethodMessage previousMessage = null;
 
        static Dictionary staticMethodMessageMap = new Dictionary();
        static Object syncRoot = new Object(); 
 
        internal MethodMessage(Type interfaceType, string methodName,
                               object[] args, String identity) : 
            this(interfaceType, methodName, args, identity, false)
        {

        } 

        internal MethodMessage(Type interfaceType, string methodName, 
                               object[] args, String identity, bool responseRequired) 
        {
            this.interfaceType = interfaceType; 
            this.methodName = methodName;
            this.args = args;
            callContext = GetLogicalCallContext();
 
            if(responseRequired)
                returnValueSignalEvent = new ManualResetEvent(false); 
 
            PopulateIdentity(callContext, identity);
            Clone(); 
        }


 
        [OnSerializing]
        void OnSerializing(StreamingContext context) 
        { 
            if (returnValueSignalEvent != null && !responseSet)
            { 
                callbackCookie = Guid.NewGuid();

                lock (syncRoot)
                { 
                    staticMethodMessageMap.Add(callbackCookie, previousMessage ?? this);
                } 
            } 
        }
 
        [OnDeserialized]
        void OnDeserialized(StreamingContext context)
        {
            if (callbackCookie != Guid.Empty) 
            {
                lock (syncRoot) 
                { 
                    if (staticMethodMessageMap.TryGetValue(callbackCookie, out previousMessage))
                        staticMethodMessageMap.Remove(callbackCookie); 
                }

                if (previousMessage != null)
                { 
                    this.responseSet = previousMessage.responseSet;
                    this.returnValueSignalEvent = previousMessage.returnValueSignalEvent; 
                } 
            }
 
            callbackCookie = Guid.Empty;
        }

        string IMethodMessage.GetArgName(int index) 
        {
            throw new NotImplementedException(); 
        } 

        object IMethodMessage.GetArg(int argNum) 
        {
            return this.clonedArgs[argNum];
        }
 
        string IMethodMessage.Uri
        { 
#pragma warning disable 56503 
            // not implemented
            get { throw new NotImplementedException(); } 
#pragma warning restore 56503
        }

        string IMethodMessage.MethodName 
        {
            get{return this.methodName;} 
        } 

        string IMethodMessage.TypeName 
        {
            get
            {
                return (this.interfaceType.ToString()); 
            }
        } 
 
        object IMethodMessage.MethodSignature
        { 
#pragma warning disable 56503
            get { throw new NotImplementedException(); }
#pragma warning restore 56503
        } 

        object[] IMethodMessage.Args 
        { 
            get
            { 
                return this.clonedArgs;
            }
        }
 
        object Clone()
        { 
            object[] clones = new object[this.args.Length]; 

            for (int i = 0; i < this.args.Length; i++ ) 
            {
                clones[i] = Clone(this.args[i]);
            }
            this.clonedArgs = clones; 
            return clones;
        } 
 
        object Clone(object source)
        { 
            if (source == null || source.GetType().IsValueType)
                return source;

            ICloneable clone = source as ICloneable; 
            if (clone != null)
                return clone.Clone(); 
 
            BinaryFormatter formatter = new BinaryFormatter();
            System.IO.MemoryStream stream = new System.IO.MemoryStream(1024); 
            try
            {
                formatter.Serialize(stream, source);
            } 
            catch (SerializationException e)
            { 
                throw new InvalidOperationException(SR.GetString(SR.Error_EventArgumentSerializationException), e); 
            }
            stream.Position = 0; 
            object cloned = formatter.Deserialize(stream);
            return cloned;
        }
 
        int IMethodMessage.ArgCount
        { 
            get { return this.clonedArgs.Length; } 
        }
 
        bool IMethodMessage.HasVarArgs
        {
#pragma warning disable 56503
            get { throw new NotImplementedException(); } 
#pragma warning restore 56503
        } 
 
        LogicalCallContext IMethodMessage.LogicalCallContext
        { 
            get{return callContext;}
        }

        MethodBase IMethodMessage.MethodBase 
        {
#pragma warning disable 56503 
            get { throw new NotImplementedException(); } 
#pragma warning restore 56503
        } 

        IDictionary System.Runtime.Remoting.Messaging.IMessage.Properties
        {
#pragma warning disable 56503 
            get { throw new NotImplementedException(); }
#pragma warning restore 56503 
        } 

        void PopulateIdentity(LogicalCallContext callContext, String identity) 
        {
           callContext.SetData(IdentityContextData.IdentityContext, new IdentityContextData(identity));
        }
 
        static LogicalCallContext singletonCallContext;
        static Object syncObject = new Object(); 
 
        static LogicalCallContext GetLogicalCallContext()
        { 
            lock (syncObject)
            {
                if (singletonCallContext == null)
                { 
                    CallContextProxy contextProxy = new CallContextProxy(typeof(IDisposable));
                    IDisposable disposable = (IDisposable)contextProxy.GetTransparentProxy(); 
                    disposable.Dispose(); 
                    singletonCallContext = contextProxy.CallContext;
                } 
                return singletonCallContext.Clone() as LogicalCallContext;
            }
        }
 
        #region IMethodResponseMessage implementation
 
        internal IMethodResponseMessage WaitForResponseMessage() 
        {
            // todo wait for certain timeout 
            this.returnValueSignalEvent.WaitOne();
            this.returnValueSignalEvent = null;
            return this;
        } 

        public void SendResponse(ICollection outArgs) 
        { 
            if (this.returnValueSignalEvent == null)
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Error_WorkflowInstanceDehydratedBeforeSendingResponse))); 

            if (!this.responseSet)
            {
                this.OutArgs = outArgs; 
                this.returnValueSignalEvent.Set();
                this.responseSet = true; 
            } 
        }
 
        public void SendException(Exception exception)
        {
            if (this.returnValueSignalEvent == null)
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Error_WorkflowInstanceDehydratedBeforeSendingResponse))); 

            if (!this.responseSet) 
            { 
                this.Exception = exception;
                this.returnValueSignalEvent.Set(); 
                this.responseSet = true;
            }
        }
 
        public Exception Exception
        { 
            get 
            {
                return this.exception; 
            }
            private set
            {
                if (previousMessage != null) 
                    previousMessage.Exception = value;
 
                this.exception = value; 
            }
        } 

        public ICollection OutArgs
        {
            get 
            {
                return this.outArgs; 
            } 
            private set
            { 
                if (previousMessage != null)
                    previousMessage.OutArgs = value;

                this.outArgs = value; 
            }
        } 
        #endregion 

        private sealed class CallContextProxy : System.Runtime.Remoting.Proxies.RealProxy 
        {
            LogicalCallContext callContext;

            internal LogicalCallContext CallContext 
            {
                get 
                { 
                    return callContext;
                } 
            }

            internal CallContextProxy(Type proxiedType) : base(proxiedType)
            { 

            } 
 
            public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)
            { 
                IMethodCallMessage methodCallMessage = msg as IMethodCallMessage;
                this.callContext = methodCallMessage.LogicalCallContext.Clone() as LogicalCallContext;
                return new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage);
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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