WorkflowInstanceContextProvider.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 / WorkflowInstanceContextProvider.cs / 1305376 / WorkflowInstanceContextProvider.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{ 
    using System.Runtime;
    using System.Runtime.Diagnostics; 
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Diagnostics;
    using System.Threading; 
    using System.Workflow.Runtime;
    using System.Diagnostics.CodeAnalysis;
    using System.Diagnostics;
 
    class WorkflowInstanceContextProvider : DurableInstanceContextProvider
    { 
        bool hasCheckedForExtension; 
        WorkflowInstanceLifetimeManagerExtension instanceLifeTimeManager;
        ServiceHostBase serviceHostBase; 
        WaitCallback workflowActivationCompleteCallback;
        WorkflowDefinitionContext workflowDefinitionContext;

 
        public WorkflowInstanceContextProvider(ServiceHostBase serviceHostBase, bool isPerCall, WorkflowDefinitionContext workflowDefinitionContext)
            : base(serviceHostBase, isPerCall) 
        { 
            if (workflowDefinitionContext == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("workflowDefinitionContext");
            }

            this.workflowDefinitionContext = workflowDefinitionContext; 
            this.serviceHostBase = serviceHostBase;
            this.workflowActivationCompleteCallback = Fx.ThunkCallback(new WaitCallback(this.OnWorkflowActivationCompleted)); 
        } 

        public WorkflowInstanceLifetimeManagerExtension InstanceLifeTimeManager 
        {
            get
            {
                if (!hasCheckedForExtension) 
                {
                    this.instanceLifeTimeManager = this.serviceHostBase.Extensions.Find(); 
                    hasCheckedForExtension = true; 
                }
                return this.instanceLifeTimeManager; 
            }
        }

        public override InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel) 
        {
            InstanceContext instanceContext = base.GetExistingInstanceContext(message, channel); 
 
            if (instanceContext != null && this.InstanceLifeTimeManager != null)
            { 
                WorkflowDurableInstance workflowDurableInstance = instanceContext.Extensions.Find();

                if (workflowDurableInstance == null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new InvalidOperationException( 
                        SR2.GetString( 
                        SR2.RequiredInstanceContextExtensionNotFound,
                        typeof(WorkflowDurableInstance).Name))); 
                }

                this.InstanceLifeTimeManager.NotifyWorkflowActivationComplete(
                    workflowDurableInstance.InstanceId, 
                    this.workflowActivationCompleteCallback,
                    new WorkflowActivationCompletedCallbackState 
                    ( 
                    workflowDurableInstance.InstanceId,
                    instanceContext), 
                    false);
            }

            return instanceContext; 
        }
 
 
        public override void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel)
        { 
            base.InitializeInstanceContext(instanceContext, message, channel);

            WorkflowDurableInstance workflowDurableInstance = instanceContext.Extensions.Find();
 
            if (workflowDurableInstance == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new InvalidOperationException(
                    SR2.GetString( 
                    SR2.RequiredInstanceContextExtensionNotFound,
                    typeof(WorkflowDurableInstance).Name)));
            }
 
            if (this.InstanceLifeTimeManager != null)
            { 
                this.InstanceLifeTimeManager.NotifyWorkflowActivationComplete(workflowDurableInstance.InstanceId, 
                    this.workflowActivationCompleteCallback,
                    new WorkflowActivationCompletedCallbackState 
                    (workflowDurableInstance.InstanceId, instanceContext),
                    false);
            }
        } 

        public override bool IsIdle(InstanceContext instanceContext) 
        { 
            if (instanceContext == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instanceContext");
            }

            WorkflowDurableInstance workflowDurableInstance = instanceContext.Extensions.Find(); 

            if (workflowDurableInstance == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException( 
                    SR2.GetString(
                    SR2.RequiredInstanceContextExtensionNotFound,
                    typeof(WorkflowDurableInstance).Name)));
            } 

            if (this.InstanceLifeTimeManager != null) 
            { 
                return (!this.InstanceLifeTimeManager.IsInstanceInMemory(workflowDurableInstance.InstanceId)) &&
                    base.IsIdle(instanceContext); 
            }
            return base.IsIdle(instanceContext);
        }
 
        public override void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext)
        { 
            WorkflowDurableInstance workflowDurableInstance = instanceContext.Extensions.Find(); 

            if (workflowDurableInstance == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(
                    SR2.GetString( 
                    SR2.RequiredInstanceContextExtensionNotFound,
                    typeof(WorkflowDurableInstance).Name))); 
            } 

            if (this.InstanceLifeTimeManager != null) 
            {
                if (this.InstanceLifeTimeManager.IsInstanceInMemory(workflowDurableInstance.InstanceId))
                {
                    this.InstanceLifeTimeManager.NotifyWorkflowActivationComplete(workflowDurableInstance.InstanceId, 
                        Fx.ThunkCallback(new WaitCallback(this.OnWorkflowActivationCompleted)),
                        new WorkflowActivationCompletedCallbackState 
                        ( 
                        workflowDurableInstance.InstanceId,
                        instanceContext, 
                        callback),
                        true);
                }
                else 
                {
                    if (base.IsIdle(instanceContext)) 
                    { 
                        callback(instanceContext);
                    } 
                    else
                    {
                        base.NotifyIdle(callback, instanceContext);
                    } 
                }
            } 
            else 
            {
                base.NotifyIdle(callback, instanceContext); 
            }
        }

        protected override DurableInstance OnCreateNewInstance(Guid instanceId) 
        {
            if (DiagnosticUtility.ShouldTraceInformation) 
            { 
                string traceText = SR2.GetString(SR2.InstanceContextProviderCreatedNewInstance, "Workflow", instanceId);
                TraceUtility.TraceEvent(TraceEventType.Information, 
                    TraceCode.ActivatingMessageReceived, SR.GetString(SR.TraceCodeActivatingMessageReceived),
                    new StringTraceRecord("NewInstanceDetail", traceText),
                    this, null);
            } 

            return new WorkflowDurableInstance(this, instanceId, this.workflowDefinitionContext, true); 
        } 

        protected override DurableInstance OnGetExistingInstance(Guid instanceId) 
        {
            return new WorkflowDurableInstance(this, instanceId, this.workflowDefinitionContext, false);
        }
 
        void OnWorkflowActivationCompleted(object state)
        { 
            WorkflowActivationCompletedCallbackState callbackState = (WorkflowActivationCompletedCallbackState) state; 

            lock (callbackState.InstanceContext.ThisLock) 
            {
                if (base.Cache.Contains(callbackState.InstanceId, callbackState.InstanceContext))
                {
                    WorkflowDurableInstance durableInstance = callbackState.InstanceContext.Extensions.Find(); 
                    if (durableInstance != null
                        && durableInstance.CurrentOperationInvocation != null 
                        && durableInstance.CurrentOperationInvocation.HasWorkflowRequestContextBeenSerialized 
                        && !durableInstance.CurrentOperationInvocation.IsCompleted)
                    { 
                        // If we are here, it means the workflow instance completed, terminated, or otherwise unloaded without
                        // completing the current operation invocation. In such case, we want to make the best effort to let
                        // service model to consider this operation invocation failed.
                        try 
                        {
                            durableInstance.CurrentOperationInvocation.SendFault( 
                                WorkflowOperationErrorHandler.CreateUnhandledException( 
                                new InvalidOperationException(SR2.GetString(SR2.WorkflowServiceUnloadedWithoutSendingResponse))),
                                null); 
                        }
                        catch (Exception e)
                        {
                            if (Fx.IsFatal(e)) 
                            {
                                throw; 
                            } 
                        }
                    } 

                    IChannel[] incomingChannels = new IChannel[callbackState.InstanceContext.IncomingChannels.Count];
                    callbackState.InstanceContext.IncomingChannels.CopyTo(incomingChannels, 0);
 
                    if (callbackState.InstanceContext.IncomingChannels.Count != 0)
                    { 
                        foreach (IChannel channel in incomingChannels) 
                        {
                            callbackState.InstanceContext.IncomingChannels.Remove(channel); 
                        }
                    }
                    else
                    { 
                        //Call notify only when IncomingChannels Collection is empty.
                        if (callbackState.InstanceContextIdleCallback != null) 
                        { 
                            callbackState.InstanceContextIdleCallback(callbackState.InstanceContext);
                        } 
                    }
                }
            }
        } 

        class WorkflowActivationCompletedCallbackState 
        { 
            InstanceContext instanceContext;
            InstanceContextIdleCallback instanceContextIdleCallback; 
            Guid instanceId;

            public WorkflowActivationCompletedCallbackState(Guid instanceId, InstanceContext instanceContext)
                : this(instanceId, instanceContext, null) 
            {
 
            } 

            public WorkflowActivationCompletedCallbackState(Guid instanceId, InstanceContext instanceContext, InstanceContextIdleCallback callback) 
            {
                this.instanceId = instanceId;
                this.instanceContext = instanceContext;
                this.instanceContextIdleCallback = callback; 
            }
 
 
            public InstanceContext InstanceContext
            { 
                get
                {
                    return this.instanceContext;
                } 
            }
 
            public InstanceContextIdleCallback InstanceContextIdleCallback 
            {
                get 
                {
                    return this.instanceContextIdleCallback;
                }
            } 

            public Guid InstanceId 
            { 
                get
                { 
                    return this.instanceId;
                }
            }
        } 
    }
} 

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