ActivityExecutorDelegateInfo.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 / Common / AuthoringOM / ActivityExecutorDelegateInfo.cs / 1305376 / ActivityExecutorDelegateInfo.cs

                            namespace System.Workflow.ComponentModel 
{
    using System;
    using System.Diagnostics;
    using System.Collections.Generic; 
    using System.ComponentModel;
    using System.Globalization; 
 
    public interface IActivityEventListener where T : EventArgs
    { 
        void OnEvent(object sender, T e);
    }

    [Serializable] 
    internal sealed class ActivityExecutorDelegateInfo where T : EventArgs
    { 
        private string activityQualifiedName = null; 
        private IActivityEventListener eventListener = null;
        private EventHandler delegateValue = null; 
        private int contextId = -1;
        private bool wantInTransact = false;
        private string subscribedActivityQualifiedName = null;
 
        public ActivityExecutorDelegateInfo(EventHandler delegateValue, Activity contextActivity)
            : this(false, delegateValue, contextActivity) 
        { 
        }
        public ActivityExecutorDelegateInfo(IActivityEventListener eventListener, Activity contextActivity) 
            : this(false, eventListener, contextActivity)
        {
        }
        public ActivityExecutorDelegateInfo(EventHandler delegateValue, Activity contextActivity, bool wantInTransact) 
            : this(delegateValue, contextActivity)
        { 
            this.wantInTransact = wantInTransact; 
        }
        public ActivityExecutorDelegateInfo(IActivityEventListener eventListener, Activity contextActivity, bool wantInTransact) 
            : this(eventListener, contextActivity)
        {
            this.wantInTransact = wantInTransact;
        } 
        internal ActivityExecutorDelegateInfo(bool useCurrentContext, EventHandler delegateValue, Activity contextActivity)
        { 
            this.delegateValue = delegateValue; 
            Activity target = delegateValue.Target as Activity;
 
            if (contextActivity.WorkflowCoreRuntime != null)
            {
                if (useCurrentContext)
                    this.contextId = contextActivity.WorkflowCoreRuntime.CurrentActivity.ContextActivity.ContextId; 
                else
                    this.contextId = contextActivity.ContextId; 
 
                this.activityQualifiedName = (target ?? contextActivity.WorkflowCoreRuntime.CurrentActivity).QualifiedName;
            } 
            else
            {
                this.contextId = 1;
                this.activityQualifiedName = (target ?? contextActivity.RootActivity).QualifiedName; 
            }
        } 
        internal ActivityExecutorDelegateInfo(bool useCurrentContext, IActivityEventListener eventListener, Activity contextActivity) 
        {
            this.eventListener = eventListener; 
            Activity target = eventListener as Activity;
            if (contextActivity.WorkflowCoreRuntime != null)
            {
                if (useCurrentContext) 
                    this.contextId = contextActivity.WorkflowCoreRuntime.CurrentActivity.ContextActivity.ContextId;
                else 
                    this.contextId = contextActivity.ContextId; 

                this.activityQualifiedName = (target ?? contextActivity.WorkflowCoreRuntime.CurrentActivity).QualifiedName; 
            }
            else
            {
                this.contextId = 1; 
                this.activityQualifiedName = (target ?? contextActivity.RootActivity).QualifiedName;
            } 
        } 
        public string ActivityQualifiedName
        { 
            get
            {
                return this.activityQualifiedName;
            } 
        }
        public string SubscribedActivityQualifiedName 
        { 
            get
            { 
                return this.subscribedActivityQualifiedName;
            }
            set
            { 
                this.subscribedActivityQualifiedName = value;
            } 
 
        }
        public int ContextId 
        {
            get
            {
                return this.contextId; 
            }
        } 
        public EventHandler HandlerDelegate 
        {
            get 
            {
                return this.delegateValue;
            }
        } 

        public IActivityEventListener EventListener 
        { 
            get
            { 
                return this.eventListener;
            }
        }		
 
 		internal void InvokeDelegate(Activity currentContextActivity, T e, bool [....], bool transacted)
		{ 
			Activity targetContextActivity = currentContextActivity.WorkflowCoreRuntime.GetContextActivityForId(this.contextId); 
            if (targetContextActivity == null)
            { 
                targetContextActivity = FindExecutorForActivityUp(currentContextActivity, this.activityQualifiedName);
                if (targetContextActivity == null)
                    targetContextActivity = FindExecutorForActivityDown(currentContextActivity, this.activityQualifiedName);
            } 
            if (targetContextActivity != null)
			    InvokeDelegate(currentContextActivity, targetContextActivity, e, [....], transacted); 
 		} 
		public void InvokeDelegate(Activity currentContextActivity, T e, bool transacted)
 		{ 
            // If in atomic and subscriber in same scope, or not in atomic scope at all
 			Activity targetContextActivity = FindExecutorForActivityUp(currentContextActivity, this.activityQualifiedName);
			if (targetContextActivity == null)
 				targetContextActivity = FindExecutorForActivityDown(currentContextActivity, this.activityQualifiedName); 

			if (targetContextActivity != null) 
			    InvokeDelegate(currentContextActivity, targetContextActivity, e, false, transacted); 
		}
 		private void InvokeDelegate(Activity currentContextActivity, Activity targetContextActivity, T e, bool [....], bool transacted) 
		{
 			ActivityExecutorDelegateOperation delegateOperation = null;
 			if(this.delegateValue != null)
				delegateOperation = new ActivityExecutorDelegateOperation(this.activityQualifiedName, this.delegateValue, e, this.ContextId); 
 			else
				delegateOperation = new ActivityExecutorDelegateOperation(this.activityQualifiedName, this.eventListener, e, this.ContextId); 
 
            bool mayInvokeDelegateNow = MayInvokeDelegateNow(currentContextActivity);
            if (mayInvokeDelegateNow && [....]) 
            {
                Activity targetActivity = targetContextActivity.GetActivityByName(this.activityQualifiedName);
                using (currentContextActivity.WorkflowCoreRuntime.SetCurrentActivity(targetActivity))
                { 
                    delegateOperation.SynchronousInvoke = true;
                    delegateOperation.Run(currentContextActivity.WorkflowCoreRuntime); 
                } 
            }
            else 
            {
                // If in atomic and subscriber not in same scope
                // Queue it on the subscriber's baseExecutor
                Activity targetActivity = targetContextActivity.GetActivityByName(this.activityQualifiedName); 
                currentContextActivity.WorkflowCoreRuntime.ScheduleItem(delegateOperation, ActivityExecutionContext.IsInAtomicTransaction(targetActivity), transacted, !mayInvokeDelegateNow);
            } 
        } 
        private bool MayInvokeDelegateNow(Activity currentContextActivity)
        { 
            // Ok to invoke right away if
            // subscriber wants to participate in the current transaction
            if ((this.activityQualifiedName == null) || (this.wantInTransact))
                return true; 

            // If not in atomic scope at all, 
            if (!ActivityExecutionContext.IsInAtomicTransaction(currentContextActivity.WorkflowCoreRuntime.CurrentActivity)) 
                return true;
 
            // Has not started executing yet, queue it up for now
            // Not letting it leak out for recv case any more
            Activity targetContextActivity = currentContextActivity.WorkflowCoreRuntime.GetContextActivityForId(this.contextId);
            if (targetContextActivity == null) 
                return false;
 
            // or in atomic and subscriber in same scope, 
            // or in an atomic scope that's not in executing state, e.g. need to fire Scope closed status
            Activity targetActivity = targetContextActivity.GetActivityByName(this.activityQualifiedName, true); 

            if (targetActivity == null)
                return false;
 
            if (ActivityExecutionContext.IsInAtomicTransaction(targetActivity) &&
                ActivityExecutionContext.IsInAtomicTransaction(currentContextActivity.WorkflowCoreRuntime.CurrentActivity)) 
                return true; 

            // If the activity receiving the subscription is the scope itself 
            if (targetActivity.MetaEquals(currentContextActivity))
                return true;

            return false; 
        }
        private Activity FindExecutorForActivityUp(Activity contextActivity, string activityQualifiedName) 
        { 
            while (contextActivity != null)
            { 
                Activity activityToFind = contextActivity.GetActivityByName(activityQualifiedName, true);
                if (activityToFind != null && activityToFind.ExecutionStatus != ActivityExecutionStatus.Initialized)
                    return contextActivity;
                contextActivity = contextActivity.ParentContextActivity; 
            }
            return contextActivity; 
        } 
        private Activity FindExecutorForActivityDown(Activity contextActivity, string activityQualifiedName)
        { 
            Queue contextActivities = new Queue();
            contextActivities.Enqueue(contextActivity);
            while (contextActivities.Count > 0)
            { 
                Activity contextActivity2 = contextActivities.Dequeue();
                Activity activityToFind = contextActivity2.GetActivityByName(activityQualifiedName, true); 
                if (activityToFind != null && activityToFind.ExecutionStatus != ActivityExecutionStatus.Initialized) 
                    return contextActivity2;
 
                IList nestedContextActivities = (IList)contextActivity2.GetValue(Activity.ActiveExecutionContextsProperty);
                if (nestedContextActivities != null)
                {
                    foreach (Activity nestedContextActivity in nestedContextActivities) 
                        contextActivities.Enqueue(nestedContextActivity);
                } 
            } 
            return null;
        } 
        public override bool Equals(object obj)
        {
            ActivityExecutorDelegateInfo otherObject = obj as ActivityExecutorDelegateInfo;
            if (otherObject == null) 
                return false;
 
            return ( 
                            (otherObject.delegateValue == null && this.delegateValue == null) ||
                            (otherObject.delegateValue != null && otherObject.delegateValue.Equals(this.delegateValue)) 
                        ) &&
                        (
                            (otherObject.eventListener == null && this.eventListener == null) ||
                            (otherObject.eventListener != null && otherObject.eventListener.Equals(this.eventListener)) 
                        ) &&
                        otherObject.activityQualifiedName == this.activityQualifiedName && 
                        otherObject.contextId == this.contextId && 
                        otherObject.wantInTransact == this.wantInTransact;
        } 
        public override int GetHashCode()
        {
            return this.delegateValue != null ? this.delegateValue.GetHashCode() : this.eventListener.GetHashCode() ^
                    this.activityQualifiedName.GetHashCode(); 
        }
 
        [Serializable] 
        private sealed class ActivityExecutorDelegateOperation : SchedulableItem
        { 
            private string activityQualifiedName = null;
            private IActivityEventListener eventListener = null;
            private EventHandler delegateValue = null;
            private T args = null; 

            [NonSerialized] 
            private bool synchronousInvoke = false; 

            public ActivityExecutorDelegateOperation(string activityQualifiedName, EventHandler delegateValue, T e, int contextId) 
                : base(contextId, activityQualifiedName)
            {
                this.activityQualifiedName = activityQualifiedName;
                this.delegateValue = delegateValue; 
                this.args = e;
            } 
            public ActivityExecutorDelegateOperation(string activityQualifiedName, IActivityEventListener eventListener, T e, int contextId) 
                : base(contextId, activityQualifiedName)
            { 
                this.activityQualifiedName = activityQualifiedName;
                this.eventListener = eventListener;
                this.args = e;
            } 
            internal bool SynchronousInvoke
            { 
                get 
                {
                    return this.synchronousInvoke; 
                }
                set
                {
                    this.synchronousInvoke = value; 
                }
            } 
            public override bool Run(IWorkflowCoreRuntime workflowCoreRuntime) 
            {
                // get context activity 
                Activity contextActivity = workflowCoreRuntime.GetContextActivityForId(this.ContextId);

                // Work around for ActivityExecutionStatusChangedEventArgs
                ActivityExecutionStatusChangedEventArgs activityStatusChangeEventArgs = this.args as ActivityExecutionStatusChangedEventArgs; 
                if (activityStatusChangeEventArgs != null)
                { 
                    activityStatusChangeEventArgs.BaseExecutor = workflowCoreRuntime; 
                    if (activityStatusChangeEventArgs.Activity == null)
                    { 
                        // status change for an activity that has been deleted dynamically since.
                        activityStatusChangeEventArgs.BaseExecutor = null;
                        return false;
                    } 
                }
 
                // get activity, if null, or if activity has already closed or just initialized, or if primary has closed and 
                // the target of the notification is not ActivityExecutionFilter, then
                Activity activity = contextActivity.GetActivityByName(this.activityQualifiedName); 
                if (    activity == null ||
                        ((activity.ExecutionStatus == ActivityExecutionStatus.Closed || activity.ExecutionStatus == ActivityExecutionStatus.Initialized) && !this.synchronousInvoke) ||
                        (activity.HasPrimaryClosed && !(this.eventListener is ActivityExecutionFilter))
                    ) 
                    return false;
 
                // call the delegate 
                try
                { 
                    using (workflowCoreRuntime.SetCurrentActivity(activity))
                    {
                        using (ActivityExecutionContext activityExecutionContext = new ActivityExecutionContext(activity))
                        { 
                            if (this.delegateValue != null)
                                this.delegateValue(activityExecutionContext, this.args); 
                            else 
                                this.eventListener.OnEvent(activityExecutionContext, this.args);
                        } 
                    }
                }
                catch (Exception e)
                { 
                    if (activity != null)
                        System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 1, "Subscription handler of Activity {0} threw {1}", activity.QualifiedName, e.ToString()); 
                    else 
                        System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 1, "Subscription handler threw {0}", e.ToString());
                    throw; 
                }
                finally
                {
                    // Work around for activity status change Event Args 
                    if (activityStatusChangeEventArgs != null)
                        activityStatusChangeEventArgs.BaseExecutor = null; 
                } 
                return true;
            } 
            public override string ToString()
            {
                return "SubscriptionEvent(" + "(" + this.ContextId.ToString(CultureInfo.CurrentCulture) + ")" + this.activityQualifiedName + ", " + this.args.ToString() + ")";
            } 
        }
    } 
} 

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