MessageRpc.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / MessageRpc.cs / 1 / MessageRpc.cs

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

namespace System.ServiceModel.Dispatcher 
{
    using System; 
    using System.ServiceModel; 
    using System.ServiceModel.Activation;
    using System.Collections.ObjectModel; 
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Diagnostics; 
    using System.IdentityModel.Claims;
    using System.IdentityModel.Policy; 
    using System.Threading; 
    using System.Xml;
    using System.Security; 

    delegate void MessageRpcProcessor(ref MessageRpc rpc);

    class RefBool 
    {
        internal bool Value = false; 
    } 

    struct MessageRpc 
    {
        internal ServiceModelActivity Activity;
        internal ManualResetEvent AsyncOperationWaitEvent;
        internal Guid ResponseActivityId; 
        internal IAsyncResult AsyncResult;
        internal readonly ServiceChannel Channel; 
        internal readonly ChannelHandler channelHandler; 
        internal RefBool CompletedSynchronously;  // only matters if op is async
        internal readonly object[] Correlation; 
        internal object[] InputParameters;
        internal object[] OutputParameters;
        internal object ReturnParameter;
        internal bool ParametersDisposed; 
        internal bool DidDeserializeRequestBody;
        internal TransactionMessageProperty TransactionMessageProperty; 
        internal TransactedBatchContext TransactedBatchContext; 
        internal Exception Error;
        internal MessageRpcProcessor ErrorProcessor; 
        internal ErrorHandlerFaultInfo FaultInfo;
        internal bool HasSecurityContext;
        internal readonly ServiceHostBase Host;
        internal object Instance; 
        internal bool MessageRpcOwnsInstanceContextThrottle;
        internal MessageRpcProcessor NextProcessor; 
        internal Collection NotUnderstoodHeaders; 
        internal DispatchOperationRuntime Operation;
        internal readonly OperationContext OperationContext; 
        bool paused;
        internal Message Request;
        internal RequestContext RequestContext;
        internal bool RequestContextThrewOnReply; 
        internal UniqueId RequestID;
        internal Message Reply; 
        internal RequestReplyCorrelator.ReplyToInfo ReplyToInfo; 
        internal MessageVersion RequestVersion;
        internal ServiceSecurityContext SecurityContext; 
        internal InstanceContext InstanceContext;
        internal bool SuccessfullyBoundInstance;
        internal bool SuccessfullyIncrementedActivity;
        internal bool SuccessfullyLockedInstance; 
        bool switchedThreads;
        bool isInstanceContextSingleton; 
        internal TransactionRpcFacet transaction; 
        internal HostingMessageProperty HostingProperty;
 
        internal MessageRpc(RequestContext requestContext, Message request, DispatchOperationRuntime operation,
                            ServiceChannel channel, ServiceHostBase host, ChannelHandler channelHandler, bool cleanThread,
                            OperationContext operationContext, InstanceContext instanceContext)
        { 
            DiagnosticUtility.DebugAssert((operationContext != null), "System.ServiceModel.Dispatcher.MessageRpc.MessageRpc(), operationContext == null");
            DiagnosticUtility.DebugAssert(channelHandler != null, "System.ServiceModel.Dispatcher.MessageRpc.MessageRpc(), channelHandler == null"); 
 
            this.AsyncOperationWaitEvent = null;
            this.Activity = null; 
            this.AsyncResult = null;
            this.Channel = channel;
            this.channelHandler = channelHandler;
            this.CompletedSynchronously = null; 
            this.Correlation = EmptyArray.Allocate(operation.Parent.CorrelationCount);
            this.DidDeserializeRequestBody = false; 
            this.TransactionMessageProperty = null; 
            this.TransactedBatchContext = null;
            this.Error = null; 
            this.ErrorProcessor = null;
            this.FaultInfo = new ErrorHandlerFaultInfo(request.Version.Addressing.DefaultFaultAction);
            this.HasSecurityContext = false;
            this.Host = host; 
            this.Instance = null;
            this.MessageRpcOwnsInstanceContextThrottle = false; 
            this.NextProcessor = null; 
            this.NotUnderstoodHeaders = null;
            this.Operation = operation; 
            this.OperationContext = operationContext;
            this.paused = false;
            this.ParametersDisposed = false;
            this.Request = request; 
            this.RequestContext = requestContext;
            this.RequestContextThrewOnReply = false; 
            this.RequestVersion = request.Version; 
            this.Reply = null;
            this.SecurityContext = null; 
            this.InstanceContext = instanceContext;
            this.SuccessfullyBoundInstance = false;
            this.SuccessfullyIncrementedActivity = false;
            this.SuccessfullyLockedInstance = false; 
            this.switchedThreads = !cleanThread;
            this.transaction = null; 
            this.InputParameters = null; 
            this.OutputParameters = null;
            this.ReturnParameter = null; 
            this.isInstanceContextSingleton = InstanceContextProviderBase.IsProviderSingleton(this.Channel.DispatchRuntime.InstanceContextProvider);

            if (!operation.IsOneWay && !operation.Parent.ManualAddressing)
            { 
                this.RequestID = request.Headers.MessageId;
                this.ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo(request); 
            } 
            else
            { 
                this.RequestID = null;
                this.ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo();
            }
 
            this.HostingProperty = null;
            object property; 
            if (ServiceHostingEnvironment.IsHosted && request.Properties.TryGetValue(HostingMessageProperty.Name, out property)) 
            {
                this.HostingProperty = (HostingMessageProperty)property; 
                request.Properties.Remove(HostingMessageProperty.Name);
            }

            if (DiagnosticUtility.ShouldUseActivity) 
            {
                this.Activity = TraceUtility.ExtractActivity(this.Request); 
            } 

            if (DiagnosticUtility.ShouldUseActivity || TraceUtility.ShouldPropagateActivity) 
            {
                this.ResponseActivityId = ActivityIdHeader.ExtractActivityId(this.Request);
            }
            else 
            {
                this.ResponseActivityId = Guid.Empty; 
            } 
        }
 
        internal bool IsPaused
        {
            get { return this.paused; }
        } 

        internal bool SwitchedThreads 
        { 
            get { return this.switchedThreads; }
        } 

        internal bool IsInstanceContextSingleton
        {
            set 
            {
                this.isInstanceContextSingleton = value; 
            } 
        }
 
        internal TransactionRpcFacet Transaction
        {
            get
            { 
                if (this.transaction == null)
                    this.transaction = new TransactionRpcFacet(ref this); 
                return this.transaction; 
            }
        } 

        internal void Abort()
        {
            this.AbortRequestContext(); 
            this.AbortChannel();
            this.AbortInstanceContext(); 
        } 

        void AbortRequestContext(RequestContext requestContext) 
        {
            try
            {
                requestContext.Abort(); 
            }
            catch (Exception e) 
            { 
                if (DiagnosticUtility.IsFatal(e))
                { 
                    throw;
                }
                this.channelHandler.HandleError(e);
            } 
        }
 
        internal void AbortRequestContext() 
        {
            if (this.OperationContext.RequestContext != null) 
            {
                this.AbortRequestContext(this.OperationContext.RequestContext);
            }
            if ((this.RequestContext != null) && (this.RequestContext != this.OperationContext.RequestContext)) 
            {
                this.AbortRequestContext(this.RequestContext); 
            } 
        }
 
        internal void CloseRequestContext()
        {
            if (this.OperationContext.RequestContext != null)
            { 
                this.DisposeRequestContext(this.OperationContext.RequestContext);
            } 
            if ((this.RequestContext != null) && (this.RequestContext != this.OperationContext.RequestContext)) 
            {
                this.DisposeRequestContext(this.RequestContext); 
            }
        }

        void DisposeRequestContext(RequestContext context) 
        {
            try 
            { 
                context.Close();
            } 
            catch (Exception e)
            {
                if (DiagnosticUtility.IsFatal(e))
                { 
                    throw;
                } 
                this.AbortRequestContext(context); 
                this.channelHandler.HandleError(e);
            } 
        }

        internal void AbortChannel()
        { 
            if ((this.Channel != null) && this.Channel.HasSession)
            { 
                try 
                {
                    this.Channel.Abort(); 
                }
                catch (Exception e)
                {
                    if (DiagnosticUtility.IsFatal(e)) 
                    {
                        throw; 
                    } 
                    this.channelHandler.HandleError(e);
                } 
            }
        }

        internal void CloseChannel() 
        {
            if ((this.Channel != null) && this.Channel.HasSession) 
            { 
                try
                { 
                    this.Channel.Close(ChannelHandler.CloseAfterFaultTimeout);
                }
                catch (Exception e)
                { 
                    if (DiagnosticUtility.IsFatal(e))
                    { 
                        throw; 
                    }
                    this.channelHandler.HandleError(e); 
                }
            }
        }
 
        internal void AbortInstanceContext()
        { 
            if (this.InstanceContext != null && !this.isInstanceContextSingleton) 
            {
                try 
                {
                    this.InstanceContext.Abort();
                }
                catch (Exception e) 
                {
                    if (DiagnosticUtility.IsFatal(e)) 
                    { 
                        throw;
                    } 
                    this.channelHandler.HandleError(e);
                }
            }
        } 

        internal void EnsureReceive() 
        { 
            using (ServiceModelActivity.BoundOperation(this.Activity))
            { 
                ChannelHandler.Register(this.channelHandler);
            }
        }
 
        bool ProcessError(Exception e)
        { 
            MessageRpcProcessor handler = this.ErrorProcessor; 
            try
            { 
                Type exceptionType = e.GetType();

                if (exceptionType.IsAssignableFrom(typeof(FaultException)))
                { 
                    if (DiagnosticUtility.ShouldTraceInformation)
                    { 
                        DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); 
                    }
                } 
                else
                {
                    if (DiagnosticUtility.ShouldTraceError)
                    { 
                        DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Error);
                    } 
                } 

                this.Error = e; 

                if (this.ErrorProcessor != null)
                {
                    this.ErrorProcessor(ref this); 
                }
 
                return (this.Error == null); 
            }
#pragma warning suppress 56500 // covered by FxCOP 
            catch (Exception e2)
            {
                if (DiagnosticUtility.IsFatal(e2))
                { 
                    throw;
                } 
 
                return ((handler != this.ErrorProcessor) && this.ProcessError(e2));
            } 
        }

        internal void DisposeParameters()
        { 
            if (this.Operation.DisposeParameters)
            { 
                this.DisposeParametersCore(); 
            }
        } 

        internal void DisposeParametersCore()
        {
            if (!this.ParametersDisposed) 
            {
                this.DisposeParameterList(this.InputParameters); 
                this.DisposeParameterList(this.OutputParameters); 

                IDisposable disposableParameter = this.ReturnParameter as IDisposable; 
                if (disposableParameter != null)
                {
                    try
                    { 
                        disposableParameter.Dispose();
                    } 
                    catch (Exception e) 
                    {
                        if (DiagnosticUtility.IsFatal(e)) 
                        {
                            throw;
                        }
                        this.channelHandler.HandleError(e); 
                    }
                } 
                this.ParametersDisposed = true; 
            }
        } 

        void DisposeParameterList(object[] parameters)
        {
            IDisposable disposableParameter = null; 
            if (parameters != null)
            { 
                foreach (Object obj in parameters) 
                {
                    disposableParameter = obj as IDisposable; 
                    if (disposableParameter != null)
                    {
                        try
                        { 
                            disposableParameter.Dispose();
                        } 
                        catch (Exception e) 
                        {
                            if (DiagnosticUtility.IsFatal(e)) 
                            {
                                throw;
                            }
                            this.channelHandler.HandleError(e); 
                        }
                    } 
                } 
            }
        } 

        internal IResumeMessageRpc Pause()
        {
            Wrapper wrapper = new Wrapper(ref this); 
            this.paused = true;
            return wrapper; 
        } 

        ///  
        /// Critical - calls SecurityCritical method ApplyHostingIntegrationContextNoInline. caller must ensure that
        ///            function is called appropriately and result is guarded and Dispose()'d correctly.
        /// 
        [SecurityCritical] 
        IDisposable ApplyHostingIntegrationContext()
        { 
            if (this.HostingProperty != null) 
            {
                return this.ApplyHostingIntegrationContextNoInline(); 
            }
            else
            {
                return null; 
            }
        } 
 
        /// 
        /// Critical - calls SecurityCritical method HostingMessageProperty.ApplyIntegrationContext. caller must ensure that 
        ///            function is called appropriately and result is guarded and Dispose()'d correctly.
        /// 
        [SecurityCritical]
        [MethodImpl(MethodImplOptions.NoInlining)] 
        IDisposable ApplyHostingIntegrationContextNoInline()
        { 
            return this.HostingProperty.ApplyIntegrationContext(); 
        }
 
        /// 
        /// Critical - calls SecurityCritical method ApplyHostingIntegrationContext.
        /// Safe - does call properly and calls Dispose, doesn't leak control of the IDisposable out of the function
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal bool Process(bool isOperationContextSet) 
        { 
            using (ServiceModelActivity.BoundOperation(this.Activity))
            { 
                if (this.NextProcessor != null)
                {
                    MessageRpcProcessor processor = this.NextProcessor;
                    this.NextProcessor = null; 

                    OperationContext originalContext; 
                    if (!isOperationContextSet) 
                    {
                        originalContext = OperationContext.Current; 
                    }
                    else
                    {
                        originalContext = null; 
                    }
 
                    ServiceHostingEnvironment.IncrementBusyCount(); 
                    IDisposable hostedIntegrationContext = this.ApplyHostingIntegrationContext();
 
                    try
                    {
                        if (!isOperationContextSet)
                        { 
                            OperationContext.Current = this.OperationContext;
                        } 
 
                        processor(ref this);
 
                        bool completed = !this.paused;
                        if (completed)
                        {
                            this.OperationContext.SetClientReply(null, false); 
                        }
                        return completed; 
                    } 
#pragma warning suppress 56500 // covered by FxCOP
                    catch (Exception e) 
                    {
                        if (DiagnosticUtility.IsFatal(e))
                        {
                            throw; 
                        }
                        if (!this.ProcessError(e)) 
                        { 
                            this.Abort();
                        } 
                    }
                    finally
                    {
                        try 
                        {
                            ServiceHostingEnvironment.DecrementBusyCount(); 
 
                            if (hostedIntegrationContext != null)
                            { 
                                hostedIntegrationContext.Dispose();
                            }

                            if (!isOperationContextSet) 
                            {
                                OperationContext.Current = originalContext; 
                            } 

                            bool completed = !this.paused; 
                            if (completed)
                            {
                                this.channelHandler.DispatchDone();
                                this.OperationContext.ClearClientReplyNoThrow(); 
                            }
                        } 
#pragma warning suppress 56500 // covered by FxCOP 
                        catch (Exception e)
                        { 
                            if (DiagnosticUtility.IsFatal(e))
                            {
                                throw;
                            } 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperFatal(e.Message, e);
                        } 
                    } 
                }
 
                return true;
            }
        }
 
        internal void UnPause()
        { 
            this.paused = false; 
        }
 
        class Wrapper : IResumeMessageRpc
        {
            MessageRpc rpc;
            bool alreadyResumed; 

            internal Wrapper(ref MessageRpc rpc) 
            { 
                this.rpc = rpc;
                if (rpc.NextProcessor == null) 
                {
                    DiagnosticUtility.DebugAssert("MessageRpc.Wrapper.Wrapper: (rpc.NextProcessor != null)");
                }
                ServiceHostingEnvironment.IncrementBusyCount(); 
            }
 
            public void Resume(out bool alreadyResumedNoLock) 
            {
                try 
                {
                    alreadyResumedNoLock = this.alreadyResumed;
                    this.alreadyResumed = true;
 
                    this.rpc.switchedThreads = true;
                    if (this.rpc.Process(false)) 
                        this.rpc.EnsureReceive(); 
                }
                finally 
                {
                    ServiceHostingEnvironment.DecrementBusyCount();
                }
            } 

            public void Resume(IAsyncResult result) 
            { 
                this.rpc.AsyncResult = result;
                using (ServiceModelActivity.BoundOperation(this.rpc.Activity, true)) 
                {
                    bool alreadyResumedNoLock;
                    this.Resume(out alreadyResumedNoLock);
                    if (alreadyResumedNoLock) 
                    {
                        string text = SR.GetString(SR.SFxMultipleCallbackFromAsyncOperation, rpc.Operation.Name); 
                        Exception error = new InvalidOperationException(text); 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error);
                    } 
                }
            }

            public void SetCompletedSynchronously() 
            {
                this.rpc.CompletedSynchronously.Value = true; 
            } 

            public ManualResetEvent AsyncOperationWaitEvent 
            {
                get { return rpc.AsyncOperationWaitEvent; }
            }
        } 
    }
} 

// 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