EventHandlers.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / EventHandlers.cs / 1305376 / EventHandlers.cs

                            namespace System.Workflow.Activities 
{
    #region Imports

    using System; 
    using System.Diagnostics;
    using System.CodeDom; 
    using System.Drawing; 
    using System.Collections;
    using System.ComponentModel; 
    using System.ComponentModel.Design;
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Design;
    using System.Collections.Generic; 
    using System.Workflow.ComponentModel.Compiler;
    using System.Workflow.Runtime; 
    using System.Workflow.Activities.Common; 

    #endregion 

    [ToolboxItem(false)]
    [Designer(typeof(EventHandlersDesigner), typeof(IDesigner))]
    [ToolboxBitmap(typeof(EventHandlersActivity), "Resources.events.png")] 
    [ActivityValidator(typeof(EventHandlersValidator))]
    [SRCategory(SR.Standard)] 
    [AlternateFlowActivityAttribute] 
    public sealed class EventHandlersActivity : CompositeActivity, IActivityEventListener
    { 
        public EventHandlersActivity()
        {
        }
 
        public EventHandlersActivity(string name)
            : base(name) 
        { 
        }
 
        #region Runtime State Specific Dependency Property
        static DependencyProperty ActivityStateProperty = DependencyProperty.Register("ActivityState", typeof(List), typeof(EventHandlersActivity));
        static DependencyProperty IsScopeCompletedProperty = DependencyProperty.Register("IsScopeCompleted", typeof(bool), typeof(EventHandlersActivity), new PropertyMetadata(false));
 
        private List ActivityState
        { 
            get 
            {
                return (List)base.GetValue(ActivityStateProperty); 
            }
            set
            {
                if (value == null) 
                    base.RemoveProperty(ActivityStateProperty);
                else 
                    base.SetValue(ActivityStateProperty, value); 
            }
        } 

        private bool IsScopeCompleted
        {
            get 
            {
                return (bool)base.GetValue(IsScopeCompletedProperty); 
            } 
            set
            { 
                base.SetValue(IsScopeCompletedProperty, value);
            }
        }
        #endregion 

        internal void UnsubscribeAndClose() 
        { 
            base.Invoke(this.OnUnsubscribeAndClose, EventArgs.Empty);
        } 

        #region Protected Methods
        protected override void OnClosed(IServiceProvider provider)
        { 
            base.RemoveProperty(EventHandlersActivity.ActivityStateProperty);
            base.RemoveProperty(EventHandlersActivity.IsScopeCompletedProperty); 
        } 

        protected override void Initialize(IServiceProvider provider) 
        {
            if (this.Parent == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_MustHaveParent));
 
            base.Initialize(provider);
        } 
 
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        { 
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");

            List eventActivitySubscribers = new List(); 
            this.ActivityState = eventActivitySubscribers;
 
            for (int i = 0; i < this.EnabledActivities.Count; ++i) 
            {
                EventDrivenActivity childActivity = this.EnabledActivities[i] as EventDrivenActivity; 
                EventHandlerEventActivitySubscriber eventDrivenSubscriber = new EventHandlerEventActivitySubscriber(childActivity);
                eventActivitySubscribers.Add(eventDrivenSubscriber);
                childActivity.EventActivity.Subscribe(executionContext, eventDrivenSubscriber);
            } 
            return ActivityExecutionStatus.Executing;
        } 
        protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext) 
        {
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext");

            if (this.ActivityState == null)
                return ActivityExecutionStatus.Closed; 

            bool scopeCompleted = this.IsScopeCompleted; 
            bool canCloseNow = true; 

            for (int i = 0; i < this.EnabledActivities.Count; ++i) 
            {
                EventDrivenActivity childActivity = this.EnabledActivities[i] as EventDrivenActivity;
                EventHandlerEventActivitySubscriber eventActivitySubscriber = this.ActivityState[i] as EventHandlerEventActivitySubscriber;
 
                eventActivitySubscriber.PendingExecutionCount = 0;
 
                ActivityExecutionContextManager contextManager = executionContext.ExecutionContextManager; 
                ActivityExecutionContext childContext = contextManager.GetExecutionContext(childActivity);
 
                if (childContext != null)
                {
                    switch (childContext.Activity.ExecutionStatus)
                    { 
                        case ActivityExecutionStatus.Canceling:
                        case ActivityExecutionStatus.Faulting: 
                            canCloseNow = false; 
                            break;
                        case ActivityExecutionStatus.Executing: 
                            childContext.CancelActivity(childContext.Activity);
                            canCloseNow = false;
                            break;
                    } 
                }
 
                if (!scopeCompleted) //UnSubscribe from event. 
                {
                    childActivity.EventActivity.Unsubscribe(executionContext, eventActivitySubscriber); 
                }
            }

            if (canCloseNow) 
            {
                this.ActivityState = null; 
                return ActivityExecutionStatus.Closed; 
            }
            else 
            {
                return this.ExecutionStatus;
            }
        } 
        protected override void OnActivityChangeAdd(ActivityExecutionContext executionContext, Activity addedActivity)
        { 
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext");
 
            if (addedActivity == null)
                throw new ArgumentNullException("addedActivity");

            EventDrivenActivity eda = addedActivity as EventDrivenActivity; 

            EventHandlersActivity activity = (EventHandlersActivity)executionContext.Activity as EventHandlersActivity; 
            EventHandlerEventActivitySubscriber eventActivitySubscriber = new EventHandlerEventActivitySubscriber(eda); 

            if (activity.ExecutionStatus == ActivityExecutionStatus.Executing && activity.ActivityState != null && !activity.IsScopeCompleted) 
            {
                eda.EventActivity.Subscribe(executionContext, eventActivitySubscriber);
                activity.ActivityState.Insert(activity.EnabledActivities.IndexOf(addedActivity), eventActivitySubscriber);
            } 
        }
        protected override void OnActivityChangeRemove(ActivityExecutionContext executionContext, Activity removedActivity) 
        { 
            if (executionContext == null)
                throw new ArgumentNullException("executionContext"); 
            if (removedActivity == null)
                throw new ArgumentNullException("removedActivity");

            EventDrivenActivity eda = removedActivity as EventDrivenActivity; 

            // find out the status of the scope 
            EventHandlersActivity activity = (EventHandlersActivity)executionContext.Activity as EventHandlersActivity; 

            if (activity.ExecutionStatus == ActivityExecutionStatus.Executing && activity.ActivityState != null && !activity.IsScopeCompleted) 
            {
                for (int i = 0; i < activity.ActivityState.Count; ++i)
                {
                    EventHandlerEventActivitySubscriber eventSubscriber = activity.ActivityState[i]; 
                    if (eventSubscriber.eventDrivenActivity.QualifiedName.Equals(removedActivity.QualifiedName))
                    { 
                        eda.EventActivity.Unsubscribe(executionContext, eventSubscriber); 
                        activity.ActivityState.RemoveAt(i);
                        return; 
                    }
                }
            }
        } 

        protected override void OnWorkflowChangesCompleted(ActivityExecutionContext executionContext) 
        { 
            if (executionContext == null)
                throw new ArgumentNullException("executionContext"); 

            base.OnWorkflowChangesCompleted(executionContext);

            if (this.ActivityState != null) 
            {
                switch (this.ExecutionStatus) 
                { 
                    case ActivityExecutionStatus.Executing:
                        if (this.IsScopeCompleted && AllHandlersAreQuiet(this, executionContext)) 
                            executionContext.CloseActivity();
                        break;
                    case ActivityExecutionStatus.Faulting:
                    case ActivityExecutionStatus.Canceling: 
                        if (AllHandlersAreQuiet(this, executionContext))
                            executionContext.CloseActivity(); 
                        break; 
                    default:
                        break; 
                }
            }
        }
        #endregion 

        #region Private Impls 
 
        #region IActivityEventListener Members
 
        void IActivityEventListener.OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            if (sender == null)
                throw new ArgumentNullException("sender"); 
            if (e == null)
                throw new ArgumentNullException("e"); 
 
            ActivityExecutionContext context = sender as ActivityExecutionContext;
            if (context == null) 
                throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender");

            EventDrivenActivity eda = e.Activity as EventDrivenActivity;
            EventHandlersActivity eventHandlers = context.Activity as EventHandlersActivity; 

            e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this); 
 
            ActivityExecutionContextManager contextManager = context.ExecutionContextManager;
            contextManager.CompleteExecutionContext(contextManager.GetExecutionContext(eda)); 

            switch (eventHandlers.ExecutionStatus)
            {
                case ActivityExecutionStatus.Executing: 
                    for (int i = 0; i < eventHandlers.EnabledActivities.Count; ++i)
                    { 
                        if (eventHandlers.EnabledActivities[i].QualifiedName.Equals(eda.QualifiedName)) 
                        {
                            EventHandlerEventActivitySubscriber eventActivitySubscriber = eventHandlers.ActivityState[i]; 

                            if (eventActivitySubscriber.PendingExecutionCount > 0)
                            {
                                eventActivitySubscriber.PendingExecutionCount--; 
                                eventActivitySubscriber.IsBlocked = false;
 
                                ActivityExecutionContext childContext = contextManager.CreateExecutionContext(eventHandlers.EnabledActivities[i]); 
                                childContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, this);
                                childContext.ExecuteActivity(childContext.Activity); 
                            }
                            else
                            {
                                eventActivitySubscriber.IsBlocked = true; 
                                if (eventHandlers.IsScopeCompleted && AllHandlersAreQuiet(eventHandlers, context))
                                    context.CloseActivity(); 
                            } 
                            break;
                        } 
                    }
                    break;

                case ActivityExecutionStatus.Canceling: 
                case ActivityExecutionStatus.Faulting:
                    if (AllHandlersAreQuiet(eventHandlers, context)) 
                        context.CloseActivity(); 
                    break;
            } 
        }

        #endregion
 
        #region Helpers
        private bool AllHandlersAreQuiet(EventHandlersActivity handlers, ActivityExecutionContext context) 
        { 
            ActivityExecutionContextManager contextManager = context.ExecutionContextManager;
 
            for (int i = 0; i < handlers.EnabledActivities.Count; ++i)
            {
                EventDrivenActivity eventDriven = handlers.EnabledActivities[i] as EventDrivenActivity;
                if (contextManager.GetExecutionContext(eventDriven) != null || (handlers.ActivityState != null && handlers.ActivityState[i].PendingExecutionCount > 0)) 
                    return false;
            } 
            return true; 
        }
        private void OnUnsubscribeAndClose(object sender, EventArgs args) 
        {
            if (sender == null)
                throw new ArgumentNullException("sender");
            if (args == null) 
                throw new ArgumentNullException("args");
 
            ActivityExecutionContext context = (ActivityExecutionContext)sender; 
            if (context == null)
                throw new ArgumentException("sender"); 

            EventHandlersActivity handlers = context.Activity as EventHandlersActivity;
            if (context.Activity.ExecutionStatus != ActivityExecutionStatus.Executing)
                return; 

            Debug.Assert(!handlers.IsScopeCompleted, "Only notified of scope body completion once"); 
            handlers.IsScopeCompleted = true; 

            ActivityExecutionContextManager contextManager = context.ExecutionContextManager; 
            bool readyToClose = true;
            for (int i = 0; i < handlers.EnabledActivities.Count; ++i)
            {
                EventDrivenActivity evtDriven = handlers.EnabledActivities[i] as EventDrivenActivity; 
                EventHandlerEventActivitySubscriber eventSubscriber = handlers.ActivityState[i];
                evtDriven.EventActivity.Unsubscribe(context, eventSubscriber); 
 
                if (contextManager.GetExecutionContext(evtDriven) != null || handlers.ActivityState[i].PendingExecutionCount != 0)
                    readyToClose = false; 
            }

            if (readyToClose)
            { 
                handlers.ActivityState = null;
                context.CloseActivity(); 
            } 
        }
        #endregion 

        #region EventSubscriber
        [Serializable]
        private sealed class EventHandlerEventActivitySubscriber : IActivityEventListener 
        {
            bool isBlocked; 
            int numOfMsgs; 

            internal EventDrivenActivity eventDrivenActivity; 

            internal EventHandlerEventActivitySubscriber(EventDrivenActivity eventDriven)
            {
                isBlocked = true; 
                numOfMsgs = 0;
                this.eventDrivenActivity = eventDriven; 
            } 

            internal bool IsBlocked 
            {
                get
                {
                    return isBlocked; 
                }
                set 
                { 
                    isBlocked = value;
                } 
            }

            internal int PendingExecutionCount
            { 
                get
                { 
                    return numOfMsgs; 
                }
                set 
                {
                    numOfMsgs = value;
                }
            } 

            void IActivityEventListener.OnEvent(object sender, QueueEventArgs e) 
            { 
                if (sender == null)
                    throw new ArgumentNullException("sender"); 
                if (e == null)
                    throw new ArgumentNullException("e");
                ActivityExecutionContext context = sender as ActivityExecutionContext;
 
                if (context == null)
                    throw new ArgumentException("sender"); 
 
                EventHandlersActivity handlers = context.Activity as EventHandlersActivity;
 
                if (handlers.ExecutionStatus != ActivityExecutionStatus.Executing)
                    return;

                if (!handlers.EnabledActivities.Contains(eventDrivenActivity)) 
                    return; //Activity is dynamically removed.
 
                if (IsBlocked) 
                {
                    IsBlocked = false; 
                    ActivityExecutionContextManager contextManager = context.ExecutionContextManager;
                    ActivityExecutionContext childContext = contextManager.CreateExecutionContext(eventDrivenActivity);
                    childContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, handlers);
                    childContext.ExecuteActivity(childContext.Activity); 
                }
                else 
                { 
                    PendingExecutionCount++;
                } 
            }
        }
        #endregion
        #endregion 

        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        private Activity GetDynamicActivity(Activity childActivity)
        { 
            if (childActivity == null)
                throw new ArgumentNullException("childActivity");

            if (!this.EnabledActivities.Contains(childActivity)) 
                throw new ArgumentException(SR.GetString(SR.Error_EventHandlersChildNotFound), "childActivity");
            else 
            { 
                Activity[] dynamicChildActivity = this.GetDynamicActivities(childActivity);
 
                if (dynamicChildActivity.Length != 0)
                    return dynamicChildActivity[0];
                else
                    return null; 
            }
        } 
 
        public Activity GetDynamicActivity(String childActivityName)
        { 
            if (childActivityName == null)
                throw new ArgumentNullException("childActivityName");

            Activity childActivity = null; 

            for (int i = 0; i < this.EnabledActivities.Count; ++i) 
            { 
                if (this.EnabledActivities[i].QualifiedName.Equals(childActivityName))
                { 
                    childActivity = this.EnabledActivities[i];
                    break;
                }
            } 

            if (childActivity != null) 
                return GetDynamicActivity(childActivity); 

            throw new ArgumentException(SR.GetString(SR.Error_EventHandlersChildNotFound), "childActivityName"); 
        }
    }

    internal sealed class EventHandlersValidator : CompositeActivityValidator 
    {
        public override ValidationErrorCollection Validate(ValidationManager manager, object obj) 
        { 
            ValidationErrorCollection validationErrors = base.Validate(manager, obj);
 
            EventHandlersActivity eventHandlers = obj as EventHandlersActivity;
            if (eventHandlers == null)
                throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(EventHandlersActivity).FullName), "obj");
 
            if (eventHandlers.Parent == null)
            { 
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_MustHaveParent), ErrorNumbers.Error_EventHandlersDeclParentNotScope)); 
                return validationErrors;
            } 

            // Parent must support event handlers
            if (!(eventHandlers.Parent is EventHandlingScopeActivity))
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_EventHandlersDeclParentNotScope, eventHandlers.Parent.QualifiedName), ErrorNumbers.Error_EventHandlersDeclParentNotScope)); 

            bool bNotAllEventHandler = false; 
            foreach (Activity activity in eventHandlers.EnabledActivities) 
            {
                if (!(activity is EventDrivenActivity)) 
                    bNotAllEventHandler = true;
            }

            // validate that all child activities are event driven activities. 
            if (bNotAllEventHandler)
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_ListenNotAllEventDriven), ErrorNumbers.Error_ListenNotAllEventDriven)); 
 
            return validationErrors;
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace System.Workflow.Activities 
{
    #region Imports

    using System; 
    using System.Diagnostics;
    using System.CodeDom; 
    using System.Drawing; 
    using System.Collections;
    using System.ComponentModel; 
    using System.ComponentModel.Design;
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Design;
    using System.Collections.Generic; 
    using System.Workflow.ComponentModel.Compiler;
    using System.Workflow.Runtime; 
    using System.Workflow.Activities.Common; 

    #endregion 

    [ToolboxItem(false)]
    [Designer(typeof(EventHandlersDesigner), typeof(IDesigner))]
    [ToolboxBitmap(typeof(EventHandlersActivity), "Resources.events.png")] 
    [ActivityValidator(typeof(EventHandlersValidator))]
    [SRCategory(SR.Standard)] 
    [AlternateFlowActivityAttribute] 
    public sealed class EventHandlersActivity : CompositeActivity, IActivityEventListener
    { 
        public EventHandlersActivity()
        {
        }
 
        public EventHandlersActivity(string name)
            : base(name) 
        { 
        }
 
        #region Runtime State Specific Dependency Property
        static DependencyProperty ActivityStateProperty = DependencyProperty.Register("ActivityState", typeof(List), typeof(EventHandlersActivity));
        static DependencyProperty IsScopeCompletedProperty = DependencyProperty.Register("IsScopeCompleted", typeof(bool), typeof(EventHandlersActivity), new PropertyMetadata(false));
 
        private List ActivityState
        { 
            get 
            {
                return (List)base.GetValue(ActivityStateProperty); 
            }
            set
            {
                if (value == null) 
                    base.RemoveProperty(ActivityStateProperty);
                else 
                    base.SetValue(ActivityStateProperty, value); 
            }
        } 

        private bool IsScopeCompleted
        {
            get 
            {
                return (bool)base.GetValue(IsScopeCompletedProperty); 
            } 
            set
            { 
                base.SetValue(IsScopeCompletedProperty, value);
            }
        }
        #endregion 

        internal void UnsubscribeAndClose() 
        { 
            base.Invoke(this.OnUnsubscribeAndClose, EventArgs.Empty);
        } 

        #region Protected Methods
        protected override void OnClosed(IServiceProvider provider)
        { 
            base.RemoveProperty(EventHandlersActivity.ActivityStateProperty);
            base.RemoveProperty(EventHandlersActivity.IsScopeCompletedProperty); 
        } 

        protected override void Initialize(IServiceProvider provider) 
        {
            if (this.Parent == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_MustHaveParent));
 
            base.Initialize(provider);
        } 
 
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        { 
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");

            List eventActivitySubscribers = new List(); 
            this.ActivityState = eventActivitySubscribers;
 
            for (int i = 0; i < this.EnabledActivities.Count; ++i) 
            {
                EventDrivenActivity childActivity = this.EnabledActivities[i] as EventDrivenActivity; 
                EventHandlerEventActivitySubscriber eventDrivenSubscriber = new EventHandlerEventActivitySubscriber(childActivity);
                eventActivitySubscribers.Add(eventDrivenSubscriber);
                childActivity.EventActivity.Subscribe(executionContext, eventDrivenSubscriber);
            } 
            return ActivityExecutionStatus.Executing;
        } 
        protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext) 
        {
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext");

            if (this.ActivityState == null)
                return ActivityExecutionStatus.Closed; 

            bool scopeCompleted = this.IsScopeCompleted; 
            bool canCloseNow = true; 

            for (int i = 0; i < this.EnabledActivities.Count; ++i) 
            {
                EventDrivenActivity childActivity = this.EnabledActivities[i] as EventDrivenActivity;
                EventHandlerEventActivitySubscriber eventActivitySubscriber = this.ActivityState[i] as EventHandlerEventActivitySubscriber;
 
                eventActivitySubscriber.PendingExecutionCount = 0;
 
                ActivityExecutionContextManager contextManager = executionContext.ExecutionContextManager; 
                ActivityExecutionContext childContext = contextManager.GetExecutionContext(childActivity);
 
                if (childContext != null)
                {
                    switch (childContext.Activity.ExecutionStatus)
                    { 
                        case ActivityExecutionStatus.Canceling:
                        case ActivityExecutionStatus.Faulting: 
                            canCloseNow = false; 
                            break;
                        case ActivityExecutionStatus.Executing: 
                            childContext.CancelActivity(childContext.Activity);
                            canCloseNow = false;
                            break;
                    } 
                }
 
                if (!scopeCompleted) //UnSubscribe from event. 
                {
                    childActivity.EventActivity.Unsubscribe(executionContext, eventActivitySubscriber); 
                }
            }

            if (canCloseNow) 
            {
                this.ActivityState = null; 
                return ActivityExecutionStatus.Closed; 
            }
            else 
            {
                return this.ExecutionStatus;
            }
        } 
        protected override void OnActivityChangeAdd(ActivityExecutionContext executionContext, Activity addedActivity)
        { 
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext");
 
            if (addedActivity == null)
                throw new ArgumentNullException("addedActivity");

            EventDrivenActivity eda = addedActivity as EventDrivenActivity; 

            EventHandlersActivity activity = (EventHandlersActivity)executionContext.Activity as EventHandlersActivity; 
            EventHandlerEventActivitySubscriber eventActivitySubscriber = new EventHandlerEventActivitySubscriber(eda); 

            if (activity.ExecutionStatus == ActivityExecutionStatus.Executing && activity.ActivityState != null && !activity.IsScopeCompleted) 
            {
                eda.EventActivity.Subscribe(executionContext, eventActivitySubscriber);
                activity.ActivityState.Insert(activity.EnabledActivities.IndexOf(addedActivity), eventActivitySubscriber);
            } 
        }
        protected override void OnActivityChangeRemove(ActivityExecutionContext executionContext, Activity removedActivity) 
        { 
            if (executionContext == null)
                throw new ArgumentNullException("executionContext"); 
            if (removedActivity == null)
                throw new ArgumentNullException("removedActivity");

            EventDrivenActivity eda = removedActivity as EventDrivenActivity; 

            // find out the status of the scope 
            EventHandlersActivity activity = (EventHandlersActivity)executionContext.Activity as EventHandlersActivity; 

            if (activity.ExecutionStatus == ActivityExecutionStatus.Executing && activity.ActivityState != null && !activity.IsScopeCompleted) 
            {
                for (int i = 0; i < activity.ActivityState.Count; ++i)
                {
                    EventHandlerEventActivitySubscriber eventSubscriber = activity.ActivityState[i]; 
                    if (eventSubscriber.eventDrivenActivity.QualifiedName.Equals(removedActivity.QualifiedName))
                    { 
                        eda.EventActivity.Unsubscribe(executionContext, eventSubscriber); 
                        activity.ActivityState.RemoveAt(i);
                        return; 
                    }
                }
            }
        } 

        protected override void OnWorkflowChangesCompleted(ActivityExecutionContext executionContext) 
        { 
            if (executionContext == null)
                throw new ArgumentNullException("executionContext"); 

            base.OnWorkflowChangesCompleted(executionContext);

            if (this.ActivityState != null) 
            {
                switch (this.ExecutionStatus) 
                { 
                    case ActivityExecutionStatus.Executing:
                        if (this.IsScopeCompleted && AllHandlersAreQuiet(this, executionContext)) 
                            executionContext.CloseActivity();
                        break;
                    case ActivityExecutionStatus.Faulting:
                    case ActivityExecutionStatus.Canceling: 
                        if (AllHandlersAreQuiet(this, executionContext))
                            executionContext.CloseActivity(); 
                        break; 
                    default:
                        break; 
                }
            }
        }
        #endregion 

        #region Private Impls 
 
        #region IActivityEventListener Members
 
        void IActivityEventListener.OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            if (sender == null)
                throw new ArgumentNullException("sender"); 
            if (e == null)
                throw new ArgumentNullException("e"); 
 
            ActivityExecutionContext context = sender as ActivityExecutionContext;
            if (context == null) 
                throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender");

            EventDrivenActivity eda = e.Activity as EventDrivenActivity;
            EventHandlersActivity eventHandlers = context.Activity as EventHandlersActivity; 

            e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this); 
 
            ActivityExecutionContextManager contextManager = context.ExecutionContextManager;
            contextManager.CompleteExecutionContext(contextManager.GetExecutionContext(eda)); 

            switch (eventHandlers.ExecutionStatus)
            {
                case ActivityExecutionStatus.Executing: 
                    for (int i = 0; i < eventHandlers.EnabledActivities.Count; ++i)
                    { 
                        if (eventHandlers.EnabledActivities[i].QualifiedName.Equals(eda.QualifiedName)) 
                        {
                            EventHandlerEventActivitySubscriber eventActivitySubscriber = eventHandlers.ActivityState[i]; 

                            if (eventActivitySubscriber.PendingExecutionCount > 0)
                            {
                                eventActivitySubscriber.PendingExecutionCount--; 
                                eventActivitySubscriber.IsBlocked = false;
 
                                ActivityExecutionContext childContext = contextManager.CreateExecutionContext(eventHandlers.EnabledActivities[i]); 
                                childContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, this);
                                childContext.ExecuteActivity(childContext.Activity); 
                            }
                            else
                            {
                                eventActivitySubscriber.IsBlocked = true; 
                                if (eventHandlers.IsScopeCompleted && AllHandlersAreQuiet(eventHandlers, context))
                                    context.CloseActivity(); 
                            } 
                            break;
                        } 
                    }
                    break;

                case ActivityExecutionStatus.Canceling: 
                case ActivityExecutionStatus.Faulting:
                    if (AllHandlersAreQuiet(eventHandlers, context)) 
                        context.CloseActivity(); 
                    break;
            } 
        }

        #endregion
 
        #region Helpers
        private bool AllHandlersAreQuiet(EventHandlersActivity handlers, ActivityExecutionContext context) 
        { 
            ActivityExecutionContextManager contextManager = context.ExecutionContextManager;
 
            for (int i = 0; i < handlers.EnabledActivities.Count; ++i)
            {
                EventDrivenActivity eventDriven = handlers.EnabledActivities[i] as EventDrivenActivity;
                if (contextManager.GetExecutionContext(eventDriven) != null || (handlers.ActivityState != null && handlers.ActivityState[i].PendingExecutionCount > 0)) 
                    return false;
            } 
            return true; 
        }
        private void OnUnsubscribeAndClose(object sender, EventArgs args) 
        {
            if (sender == null)
                throw new ArgumentNullException("sender");
            if (args == null) 
                throw new ArgumentNullException("args");
 
            ActivityExecutionContext context = (ActivityExecutionContext)sender; 
            if (context == null)
                throw new ArgumentException("sender"); 

            EventHandlersActivity handlers = context.Activity as EventHandlersActivity;
            if (context.Activity.ExecutionStatus != ActivityExecutionStatus.Executing)
                return; 

            Debug.Assert(!handlers.IsScopeCompleted, "Only notified of scope body completion once"); 
            handlers.IsScopeCompleted = true; 

            ActivityExecutionContextManager contextManager = context.ExecutionContextManager; 
            bool readyToClose = true;
            for (int i = 0; i < handlers.EnabledActivities.Count; ++i)
            {
                EventDrivenActivity evtDriven = handlers.EnabledActivities[i] as EventDrivenActivity; 
                EventHandlerEventActivitySubscriber eventSubscriber = handlers.ActivityState[i];
                evtDriven.EventActivity.Unsubscribe(context, eventSubscriber); 
 
                if (contextManager.GetExecutionContext(evtDriven) != null || handlers.ActivityState[i].PendingExecutionCount != 0)
                    readyToClose = false; 
            }

            if (readyToClose)
            { 
                handlers.ActivityState = null;
                context.CloseActivity(); 
            } 
        }
        #endregion 

        #region EventSubscriber
        [Serializable]
        private sealed class EventHandlerEventActivitySubscriber : IActivityEventListener 
        {
            bool isBlocked; 
            int numOfMsgs; 

            internal EventDrivenActivity eventDrivenActivity; 

            internal EventHandlerEventActivitySubscriber(EventDrivenActivity eventDriven)
            {
                isBlocked = true; 
                numOfMsgs = 0;
                this.eventDrivenActivity = eventDriven; 
            } 

            internal bool IsBlocked 
            {
                get
                {
                    return isBlocked; 
                }
                set 
                { 
                    isBlocked = value;
                } 
            }

            internal int PendingExecutionCount
            { 
                get
                { 
                    return numOfMsgs; 
                }
                set 
                {
                    numOfMsgs = value;
                }
            } 

            void IActivityEventListener.OnEvent(object sender, QueueEventArgs e) 
            { 
                if (sender == null)
                    throw new ArgumentNullException("sender"); 
                if (e == null)
                    throw new ArgumentNullException("e");
                ActivityExecutionContext context = sender as ActivityExecutionContext;
 
                if (context == null)
                    throw new ArgumentException("sender"); 
 
                EventHandlersActivity handlers = context.Activity as EventHandlersActivity;
 
                if (handlers.ExecutionStatus != ActivityExecutionStatus.Executing)
                    return;

                if (!handlers.EnabledActivities.Contains(eventDrivenActivity)) 
                    return; //Activity is dynamically removed.
 
                if (IsBlocked) 
                {
                    IsBlocked = false; 
                    ActivityExecutionContextManager contextManager = context.ExecutionContextManager;
                    ActivityExecutionContext childContext = contextManager.CreateExecutionContext(eventDrivenActivity);
                    childContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, handlers);
                    childContext.ExecuteActivity(childContext.Activity); 
                }
                else 
                { 
                    PendingExecutionCount++;
                } 
            }
        }
        #endregion
        #endregion 

        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        private Activity GetDynamicActivity(Activity childActivity)
        { 
            if (childActivity == null)
                throw new ArgumentNullException("childActivity");

            if (!this.EnabledActivities.Contains(childActivity)) 
                throw new ArgumentException(SR.GetString(SR.Error_EventHandlersChildNotFound), "childActivity");
            else 
            { 
                Activity[] dynamicChildActivity = this.GetDynamicActivities(childActivity);
 
                if (dynamicChildActivity.Length != 0)
                    return dynamicChildActivity[0];
                else
                    return null; 
            }
        } 
 
        public Activity GetDynamicActivity(String childActivityName)
        { 
            if (childActivityName == null)
                throw new ArgumentNullException("childActivityName");

            Activity childActivity = null; 

            for (int i = 0; i < this.EnabledActivities.Count; ++i) 
            { 
                if (this.EnabledActivities[i].QualifiedName.Equals(childActivityName))
                { 
                    childActivity = this.EnabledActivities[i];
                    break;
                }
            } 

            if (childActivity != null) 
                return GetDynamicActivity(childActivity); 

            throw new ArgumentException(SR.GetString(SR.Error_EventHandlersChildNotFound), "childActivityName"); 
        }
    }

    internal sealed class EventHandlersValidator : CompositeActivityValidator 
    {
        public override ValidationErrorCollection Validate(ValidationManager manager, object obj) 
        { 
            ValidationErrorCollection validationErrors = base.Validate(manager, obj);
 
            EventHandlersActivity eventHandlers = obj as EventHandlersActivity;
            if (eventHandlers == null)
                throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(EventHandlersActivity).FullName), "obj");
 
            if (eventHandlers.Parent == null)
            { 
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_MustHaveParent), ErrorNumbers.Error_EventHandlersDeclParentNotScope)); 
                return validationErrors;
            } 

            // Parent must support event handlers
            if (!(eventHandlers.Parent is EventHandlingScopeActivity))
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_EventHandlersDeclParentNotScope, eventHandlers.Parent.QualifiedName), ErrorNumbers.Error_EventHandlersDeclParentNotScope)); 

            bool bNotAllEventHandler = false; 
            foreach (Activity activity in eventHandlers.EnabledActivities) 
            {
                if (!(activity is EventDrivenActivity)) 
                    bNotAllEventHandler = true;
            }

            // validate that all child activities are event driven activities. 
            if (bNotAllEventHandler)
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_ListenNotAllEventDriven), ErrorNumbers.Error_ListenNotAllEventDriven)); 
 
            return validationErrors;
        } 
    }
}

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