Pick.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 / NetFx40 / System.Activities / System / Activities / Statements / Pick.cs / 1407647 / Pick.cs

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

namespace System.Activities.Statements 
{
    using System.Collections.ObjectModel; 
    using System.Diagnostics.CodeAnalysis; 
    using System.Runtime;
    using System.Runtime.Collections; 
    using System.Runtime.Serialization;
    using System.Windows.Markup;

    [ContentProperty("Branches")] 
    public sealed class Pick : NativeActivity
    { 
        const string pickStateProperty = "System.Activities.Statements.Pick.PickState"; 

        Collection branches; 
        Variable pickStateVariable;
        Collection branchBodies;

        public Pick() 
        {
            this.pickStateVariable = new Variable(); 
        } 

        protected override bool CanInduceIdle 
        {
            get
            {
                return true; 
            }
        } 
 
        public Collection Branches
        { 
            get
            {
                if (this.branches == null)
                { 
                    this.branches = new ValidatingCollection
                    { 
                        // disallow null values 
                        OnAddValidationCallback = item =>
                        { 
                            if (item == null)
                            {
                                throw FxTrace.Exception.ArgumentNull("item");
                            } 
                        }
                    }; 
                } 
                return this.branches;
            } 
        }

        protected override void CacheMetadata(NativeActivityMetadata metadata)
        { 
            if (this.branchBodies == null)
            { 
                this.branchBodies = new Collection(); 
            }
            else 
            {
                this.branchBodies.Clear();
            }
 
            foreach (PickBranch branch in this.Branches)
            { 
                if (branch.Trigger == null) 
                {
                    metadata.AddValidationError(SR.PickBranchRequiresTrigger(branch.DisplayName)); 
                }

                PickBranchBody pickBranchBody = new PickBranchBody
                { 
                    Action = branch.Action,
                    DisplayName = branch.DisplayName, 
                    Trigger = branch.Trigger, 
                    Variables = branch.Variables,
                }; 

                this.branchBodies.Add(pickBranchBody);
            }
 
            metadata.SetChildrenCollection(this.branchBodies);
 
            metadata.AddImplementationVariable(this.pickStateVariable); 
        }
 
        protected override void Execute(NativeActivityContext context)
        {
            if (this.branchBodies.Count == 0)
            { 
                 return;
            } 
 
            PickState pickState = new PickState();
            this.pickStateVariable.Set(context, pickState); 

            pickState.TriggerCompletionBookmark = context.CreateBookmark(new BookmarkCallback(OnTriggerComplete));

            context.Properties.Add(pickStateProperty, pickState); 

            CompletionCallback onBranchCompleteCallback = new CompletionCallback(OnBranchComplete); 
 
            //schedule every branch to only run trigger
            for (int i = this.branchBodies.Count - 1; i >= 0; i--) 
            {
                context.ScheduleActivity(this.branchBodies[i], onBranchCompleteCallback);
            }
        } 

        protected override void Cancel(NativeActivityContext context) 
        { 
            context.CancelChildren();
        } 

        void OnBranchComplete(NativeActivityContext context, ActivityInstance completedInstance)
        {
            PickState pickState = this.pickStateVariable.Get(context); 
            ReadOnlyCollection executingChildren = context.GetChildren();
 
            switch (completedInstance.State) 
            {
                case ActivityInstanceState.Closed: 
                    pickState.HasBranchCompletedSuccessfully = true;
                    break;
                case ActivityInstanceState.Canceled:
                case ActivityInstanceState.Faulted: 
                    if (context.IsCancellationRequested)
                    { 
                        if (executingChildren.Count == 0 && !pickState.HasBranchCompletedSuccessfully) 
                        {
                            // All of the branches are complete and we haven't had a single 
                            // one complete successfully and we've been asked to cancel.
                            context.MarkCanceled();
                            context.RemoveAllBookmarks();
                        } 
                    }
                    break; 
            } 

            //the last branch should always resume action bookmark if it's still there 
            if (executingChildren.Count == 1 && pickState.ExecuteActionBookmark != null)
            {
                ResumeExecutionActionBookmark(pickState, context);
            } 
        }
 
        void OnTriggerComplete(NativeActivityContext context, Bookmark bookmark, object state) 
        {
            PickState pickState = this.pickStateVariable.Get(context); 

            string winningBranch = (string)state;

            ReadOnlyCollection children = context.GetChildren(); 

            bool resumeAction = true; 
 
            for (int i = 0; i < children.Count; i++)
            { 
                ActivityInstance child = children[i];

                if (child.Id != winningBranch)
                { 
                    context.CancelChild(child);
                    resumeAction = false; 
                } 
            }
 
            if (resumeAction)
            {
                ResumeExecutionActionBookmark(pickState, context);
            } 
        }
 
        void ResumeExecutionActionBookmark(PickState pickState, NativeActivityContext context) 
        {
            Fx.Assert(pickState.ExecuteActionBookmark != null, "This should have been set by the branch."); 

            context.ResumeBookmark(pickState.ExecuteActionBookmark, null);
            pickState.ExecuteActionBookmark = null;
        } 

        [DataContract] 
        class PickState 
        {
            [DataMember(EmitDefaultValue = false)] 
            public bool HasBranchCompletedSuccessfully
            {
                get;
                set; 
            }
 
            [DataMember(EmitDefaultValue = false)] 
            public Bookmark TriggerCompletionBookmark
            { 
                get;
                set;
            }
 
            [DataMember(EmitDefaultValue = false)]
            public Bookmark ExecuteActionBookmark 
            { 
                get;
                set; 
            }
        }

        class PickBranchBody : NativeActivity 
        {
            public PickBranchBody() 
            { 
            }
 
            protected override bool CanInduceIdle
            {
                get
                { 
                    return true;
                } 
            } 

            public Collection Variables 
            {
                get;
                set;
            } 

            public Activity Trigger 
            { 
                get;
                set; 
            }

            public Activity Action
            { 
                get;
                set; 
            } 

            protected override void CacheMetadata(NativeActivityMetadata metadata) 
            {
                Collection children = null;

                if (this.Trigger != null) 
                {
                    ActivityUtilities.Add(ref children, this.Trigger); 
                } 
                if (this.Action != null)
                { 
                    ActivityUtilities.Add(ref children, this.Action);
                }

                metadata.SetChildrenCollection(children); 

                metadata.SetVariablesCollection(this.Variables); 
            } 

            protected override void Execute(NativeActivityContext context) 
            {
                Fx.Assert(this.Trigger != null, "We validate that the trigger is not null in Pick.CacheMetadata");

                context.ScheduleActivity(this.Trigger, new CompletionCallback(OnTriggerCompleted)); 
            }
 
            void OnTriggerCompleted(NativeActivityContext context, ActivityInstance completedInstance) 
            {
                PickState pickState = (PickState)context.Properties.Find(pickStateProperty); 

                if (completedInstance.State == ActivityInstanceState.Closed && pickState.TriggerCompletionBookmark != null)
                {
                    // We're the first trigger!  We win! 
                    context.ResumeBookmark(pickState.TriggerCompletionBookmark, context.ActivityInstanceId);
                    pickState.TriggerCompletionBookmark = null; 
                    pickState.ExecuteActionBookmark = context.CreateBookmark(new BookmarkCallback(OnExecuteAction)); 
                }
                else if (!context.IsCancellationRequested) 
                {
                    // We didn't win, but we haven't been requested to cancel yet.
                    // We'll just create a bookmark to keep ourselves from completing.
                    context.CreateBookmark(); 
                }
                // else 
                // { 
                //     No need for an else since default cancelation will cover it!
                // } 
            }

            void OnExecuteAction(NativeActivityContext context, Bookmark bookmark, object state)
            { 
                if (this.Action != null)
                { 
                    context.ScheduleActivity(this.Action); 
                }
            } 
        }
    }
}

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