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"; Collectionbranches; 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SafeCloseHandleCritical.cs
- XmlElementAttributes.cs
- ICspAsymmetricAlgorithm.cs
- _CacheStreams.cs
- OracleConnectionStringBuilder.cs
- SelectedDatesCollection.cs
- SqlProviderServices.cs
- _SecureChannel.cs
- XpsSerializerWriter.cs
- InteropAutomationProvider.cs
- Drawing.cs
- FormClosingEvent.cs
- RepeaterItem.cs
- XmlDownloadManager.cs
- EventItfInfo.cs
- FlowchartDesignerCommands.cs
- XmlSchemaNotation.cs
- BrowserTree.cs
- TableAutomationPeer.cs
- Hash.cs
- TypeToken.cs
- HitTestFilterBehavior.cs
- CollectionDataContractAttribute.cs
- DispatchWrapper.cs
- SkipStoryboardToFill.cs
- BooleanFacetDescriptionElement.cs
- Query.cs
- EncoderReplacementFallback.cs
- WrapperEqualityComparer.cs
- NumberEdit.cs
- CalendarAutomationPeer.cs
- PrintDialogException.cs
- PixelShader.cs
- SelectionService.cs
- EntityProviderServices.cs
- TableLayoutPanel.cs
- QuotedPrintableStream.cs
- IntSecurity.cs
- CqlGenerator.cs
- CapabilitiesUse.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- DataMisalignedException.cs
- XamlFrame.cs
- SamlAttribute.cs
- ISFTagAndGuidCache.cs
- PixelFormats.cs
- CodeAttributeDeclarationCollection.cs
- RequestSecurityTokenSerializer.cs
- TypeUsageBuilder.cs
- ProtocolElementCollection.cs
- SqlNamer.cs
- DbUpdateCommandTree.cs
- TextRangeSerialization.cs
- ClientScriptManager.cs
- ApplicationInterop.cs
- CultureTable.cs
- DrawListViewColumnHeaderEventArgs.cs
- Boolean.cs
- ScrollData.cs
- ManifestSignatureInformation.cs
- ObjRef.cs
- loginstatus.cs
- SafeIUnknown.cs
- BaseCollection.cs
- RelationshipConverter.cs
- HttpListener.cs
- CodeComment.cs
- TabItem.cs
- Clause.cs
- SmiGettersStream.cs
- EntityDataSourceDesignerHelper.cs
- EventlogProvider.cs
- BrowserCapabilitiesFactoryBase.cs
- DataTemplate.cs
- ModifierKeysValueSerializer.cs
- Executor.cs
- XmlDeclaration.cs
- CompositionDesigner.cs
- ConfigurationSectionHelper.cs
- HtmlControl.cs
- PathHelper.cs
- Splitter.cs
- BinHexEncoder.cs
- RegexTree.cs
- SqlRecordBuffer.cs
- Automation.cs
- SiteMapNodeItem.cs
- SimpleRecyclingCache.cs
- UserNameSecurityTokenProvider.cs
- HiddenFieldPageStatePersister.cs
- TreeNodeBinding.cs
- GeneralTransform.cs
- IsolatedStorage.cs
- MonitoringDescriptionAttribute.cs
- WebPartRestoreVerb.cs
- CollectionChangedEventManager.cs
- ServiceOperationInvoker.cs
- EventLogPermissionEntry.cs
- VarRemapper.cs
- SelectionProcessor.cs