WorkflowOperationAsyncResult.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 / NetFx35 / System.WorkflowServices / System / ServiceModel / Dispatcher / WorkflowOperationAsyncResult.cs / 1305376 / WorkflowOperationAsyncResult.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{ 
    using System.Collections.Generic;
    using System.Runtime; 
    using System.Runtime.Diagnostics; 
    using System.ServiceModel.Channels;
    using System.ServiceModel.Diagnostics; 
    using System.Threading;
    using System.Workflow.Runtime;
    using System.Workflow.Runtime.Hosting;
    using System.Diagnostics; 

    sealed class WorkflowOperationAsyncResult : AsyncResult 
    { 
        static readonly object[] emptyObjectArray = new object[] { };
 
        static Action waitCallback = new Action(WorkflowOperationAsyncResult.DoWork);
        static SendOrPostCallback sendOrPostCallback = Fx.ThunkCallback(new SendOrPostCallback(waitCallback));

        Guid instanceIdGuid; 
        string instanceIdString;
        bool isOneway; 
        IDictionary outgoingContextProperties = SerializableReadOnlyDictionary.Empty; 
        object[] outputs = emptyObjectArray;
        object returnValue; 
        long time;

        public WorkflowOperationAsyncResult(WorkflowOperationInvoker workflowOperationInvoker,
            WorkflowDurableInstance workflowDurableInstance, object[] inputs, 
            AsyncCallback callback, object state, long time)
            : base(callback, state) 
        { 
            if (inputs == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inputs");
            }

            if (workflowDurableInstance == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("workflowDurableInstance"); 
            } 

            if (workflowOperationInvoker == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("workflowOperationInvoker");
            }
 
            string queueName;
 
            WorkflowRequestContext workflowRequestContext = new WorkflowRequestContext( 
                this,
                inputs, 
                GetContextProperties());

            queueName = workflowOperationInvoker.StaticQueueName;
 
            if (workflowRequestContext.ContextProperties.Count > 1) //DurableDispatchContextProperty.
            { 
                queueName = QueueNameHelper.Create(workflowOperationInvoker.StaticQueueName, workflowRequestContext.ContextProperties); 
            }
 
            WorkflowInstance workflowInstance = workflowDurableInstance.GetWorkflowInstance
                (workflowOperationInvoker.CanCreateInstance);

            AsyncCallbackState callbackState = new AsyncCallbackState(workflowRequestContext, 
                workflowInstance, workflowOperationInvoker.DispatchRuntime.SynchronizationContext,
                workflowOperationInvoker.InstanceLifetimeManager, queueName); 
 
            this.isOneway = workflowOperationInvoker.IsOneWay;
            this.instanceIdGuid = workflowInstance.InstanceId; 
            this.time = time;

            ActionItem.Schedule(waitCallback, callbackState);
 
            if (DiagnosticUtility.ShouldTraceVerbose)
            { 
                string traceText = SR2.GetString(SR2.WorkflowOperationInvokerItemQueued, this.InstanceId, queueName); 
                TraceUtility.TraceEvent(TraceEventType.Verbose,
                    TraceCode.WorkflowOperationInvokerItemQueued, SR.GetString(SR.TraceCodeWorkflowOperationInvokerItemQueued), 
                    new StringTraceRecord("ItemDetails", traceText),
                    this, null);
            }
        } 

        public long BeginTime 
        { 
            get
            { 
                return this.time;
            }
        }
 
        public bool HasWorkflowRequestContextBeenSerialized
        { 
            get; 
            set;
        } 

        internal string InstanceId
        {
            get 
            {
                if (this.instanceIdString == null) 
                { 
                    Fx.Assert(!this.instanceIdGuid.Equals(Guid.Empty), "WorkflowOperationInvokerAsyncResut.instanceIdGuid != Guid.Empty");
                    this.instanceIdString = this.instanceIdGuid.ToString(); 
                }

                return this.instanceIdString;
            } 
        }
 
        public static object End(WorkflowOperationAsyncResult result, out object[] outputs) 
        {
            if (result == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
            }
 
            try
            { 
                AsyncResult.End(result); 
            }
            finally 
            {
                //Application Fault's should carry Context Properties
                result.PromoteContextProperties();
            } 

            outputs = result.outputs; 
            return result.returnValue; 
        }
 
        public void SendFault(Exception exception, IDictionary contextProperties)
        {
            if (exception == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exception");
            } 
 
            if (!IsCompleted)
            { 
                this.outgoingContextProperties = (contextProperties != null) ? new ContextDictionary(contextProperties) : null;
            }
            base.Complete(false, exception);
        } 

        public void SendResponse(object returnValue, object[] outputs, IDictionary contextProperties) 
        { 
            if (outputs == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("outputs");
            }

            if (!IsCompleted) 
            {
                this.returnValue = returnValue; 
                this.outputs = outputs; 
                this.outgoingContextProperties = (contextProperties != null) ? new ContextDictionary(contextProperties) : null;
            } 
            base.Complete(false);
        }

        //No-op for two-ways. 
        internal void MarkOneWayOperationCompleted()
        { 
            if (this.isOneway && !this.IsCompleted) 
            {
                base.Complete(false); 
            }
        }

        static void DoWork(object state) 
        {
            if (state == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("state");
            } 

            AsyncCallbackState callbackState = (AsyncCallbackState) state;

            bool executingWork = false; 
            try
            { 
                //If SyncContext is enabled 
                //We have to do another post to get to correct thread.
                if (callbackState.SynchronizationContext != null) 
                {
                    SynchronizationContext synchronizationContext = callbackState.SynchronizationContext;
                    callbackState.SynchronizationContext = null;
 
                    SynchronizationContextWorkflowSchedulerService.
                        SynchronizationContextPostHelper.Post( 
                        synchronizationContext, 
                        WorkflowOperationAsyncResult.sendOrPostCallback,
                        callbackState); 
                }
                else //We are in correct thread to do the work.
                {
                    using (new WorkflowDispatchContext(true)) 
                    {
                        callbackState.WorkflowRequestContext.SetOperationBegin(); 
                        executingWork = true; 

                        if (callbackState.WorkflowInstanceLifeTimeManager != null) 
                        {
                            callbackState.WorkflowInstanceLifeTimeManager.NotifyMessageArrived(callbackState.WorkflowInstance.InstanceId);
                        }
 
                        callbackState.WorkflowInstance.
                            EnqueueItemOnIdle( 
                            callbackState.QueueName, 
                            callbackState.WorkflowRequestContext,
                            null, 
                            null);
                    }
                }
            } 
            catch (QueueException e)
            { 
                WorkflowOperationFault operationFault = new WorkflowOperationFault(e.ErrorCode); 

                try 
                {
                    if (callbackState.WorkflowInstanceLifeTimeManager != null)
                    {
                        callbackState.WorkflowInstanceLifeTimeManager.ScheduleTimer(callbackState.WorkflowInstance.InstanceId); 
                    }
                    callbackState.WorkflowRequestContext.SendFault(new FaultException(operationFault), null); 
                } 
                catch (Exception unhandled)
                { 
                    if (Fx.IsFatal(unhandled))
                    {
                        throw;
                    } 
                    // ignore exception; we made best effort to propagate the exception back to the invoker thread
                } 
            } 
            catch (Exception e)
            { 
                if (Fx.IsFatal(e))
                {
                    throw;
                } 

                try 
                { 
                    if (callbackState.WorkflowInstanceLifeTimeManager != null)
                    { 
                        callbackState.WorkflowInstanceLifeTimeManager.ScheduleTimer(callbackState.WorkflowInstance.InstanceId);
                    }
                    //We should field only user code exception; Everything else should go abort path.
                    callbackState.WorkflowRequestContext.GetAsyncResult().SendFault(e, null); 
                }
                catch (Exception e1) 
                { 
                    if (Fx.IsFatal(e1))
                    { 
                        throw;
                    }
                    // ignore exception; we made best effort to propagate the exception back to the invoker thread
                } 
            }
            finally 
            { 
                try
                { 
                    if (executingWork)
                    {
                        callbackState.WorkflowRequestContext.SetOperationCompleted();
                    } 
                }
                catch (Exception e1) 
                { 
                    if (Fx.IsFatal(e1))
                    { 
                        throw;
                    }

                    // ignore exception; we made best effort to propagate the exception back to the invoker thread                    } 
                }
            } 
        } 

        IDictionary GetContextProperties() 
        {
            Fx.Assert(OperationContext.Current != null, "Called from non service thread");

            ContextMessageProperty incomingContextProperties = null; 
            if (OperationContext.Current.IncomingMessageProperties != null
                && ContextMessageProperty.TryGet(OperationContext.Current.IncomingMessageProperties, out incomingContextProperties)) 
            { 
                return incomingContextProperties.Context;
            } 
            else
            {
                return SerializableReadOnlyDictionary.Empty;
            } 
        }
 
        void PromoteContextProperties() 
        {
            Fx.Assert(OperationContext.Current != null, "Called from non service thread"); 

            if (outgoingContextProperties != null)
            {
                ContextMessageProperty context; 
                if (!ContextMessageProperty.TryGet(OperationContext.Current.OutgoingMessageProperties, out context))
                { 
                    new ContextMessageProperty(this.outgoingContextProperties).AddOrReplaceInMessageProperties(OperationContext.Current.OutgoingMessageProperties); 
                }
                else 
                {
                    foreach (KeyValuePair contextElement in this.outgoingContextProperties)
                    {
                        context.Context[contextElement.Key] = contextElement.Value; 
                    }
                } 
            } 
        }
 
        class AsyncCallbackState
        {
            WorkflowInstanceLifetimeManagerExtension instanceLifeTimeManager;
            IComparable queueName; 
            SynchronizationContext synchronizationContext;
            WorkflowInstance workflowInstance; 
            WorkflowRequestContext workflowRequestContext; 

            public AsyncCallbackState( 
                WorkflowRequestContext workflowRequestContext,
                WorkflowInstance workflowInstance,
                SynchronizationContext synchronizationContext,
                WorkflowInstanceLifetimeManagerExtension instanceLifeTimeManager, 
                IComparable queueName)
            { 
                this.workflowInstance = workflowInstance; 
                this.workflowRequestContext = workflowRequestContext;
                this.synchronizationContext = synchronizationContext; 
                this.queueName = queueName;
                this.instanceLifeTimeManager = instanceLifeTimeManager;
            }
 
            public IComparable QueueName
            { 
                get 
                {
                    return this.queueName; 
                }
            }

            public SynchronizationContext SynchronizationContext 
            {
                get 
                { 
                    return this.synchronizationContext;
                } 
                set
                {
                    this.synchronizationContext = value;
                } 
            }
 
            public WorkflowInstance WorkflowInstance 
            {
                get 
                {
                    return this.workflowInstance;
                }
            } 

            public WorkflowInstanceLifetimeManagerExtension WorkflowInstanceLifeTimeManager 
            { 
                get
                { 
                    return this.instanceLifeTimeManager;
                }
            }
 
            public WorkflowRequestContext WorkflowRequestContext
            { 
                get 
                {
                    return this.workflowRequestContext; 
                }
            }
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

                        

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