Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / Listen.cs / 1305376 / Listen.cs
namespace System.Workflow.Activities { #region Imports using System; using System.Text; using System.Reflection; using System.Collections; using System.CodeDom; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing.Design; using System.Drawing; using System.Diagnostics; using System.Workflow.ComponentModel; using System.Workflow.Runtime; using System.Workflow.ComponentModel.Design; using System.Runtime.Serialization; using System.Collections.Generic; using System.Workflow.ComponentModel.Compiler; using System.Workflow.Activities.Common; #endregion [SRDescription(SR.ListenActivityDescription)] [ToolboxItem(typeof(ListenToolboxItem))] [Designer(typeof(ListenDesigner), typeof(IDesigner))] [ToolboxBitmap(typeof(ListenActivity), "Resources.Listen.png")] [ActivityValidator(typeof(ListenValidator))] [SRCategory(SR.Standard)] public sealed class ListenActivity: CompositeActivity, IActivityEventListener{ #region Constructors public ListenActivity() { } public ListenActivity(string name) : base(name) { } #endregion #region Protected methods protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { if (executionContext == null) throw new ArgumentNullException("executionContext"); List eventActivitySubscribers = new List (); this.ActivityState = eventActivitySubscribers; //Subscribe to all EventDriven Children. for (int i = 0; i < this.EnabledActivities.Count; ++i) { EventDrivenActivity eventDriven = this.EnabledActivities[i] as EventDrivenActivity; ListenEventActivitySubscriber eventActivitySubscriber = new ListenEventActivitySubscriber(eventDriven); eventDriven.EventActivity.Subscribe(executionContext, eventActivitySubscriber); eventActivitySubscribers.Add(eventActivitySubscriber); } return ActivityExecutionStatus.Executing; } protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext) { if (executionContext == null) throw new ArgumentNullException("executionContext"); if (this.ActivityState == null) return ActivityExecutionStatus.Closed; try { if (this.IsListenTrigerred) { //We need to cancel the active running branch for (int i = 0; i < this.EnabledActivities.Count; ++i) { EventDrivenActivity eventDriven = this.EnabledActivities[i] as EventDrivenActivity; if (eventDriven.ExecutionStatus == ActivityExecutionStatus.Executing) { executionContext.CancelActivity(eventDriven); return ActivityExecutionStatus.Canceling; } //If the branch is faulting let it close. else if (eventDriven.ExecutionStatus == ActivityExecutionStatus.Faulting) { return ActivityExecutionStatus.Canceling; } } } else { //Everything is passive. Lets unsubscribe all and close. for (int i = 0; i < this.ActivityState.Count; ++i) { EventDrivenActivity eventDrivenChild = this.EnabledActivities[i] as EventDrivenActivity; ListenEventActivitySubscriber eventActivitySubscriber = this.ActivityState[i]; eventDrivenChild.EventActivity.Unsubscribe(executionContext, eventActivitySubscriber); } } } finally { // We null out ActivityState in the finally block to ensure that if // eventDrivenChild.EventActivity.Unsubscribe above throws then the // Cancel method does not get called repeatedly. this.ActivityState = null; } return ActivityExecutionStatus.Closed; } protected override void OnClosed(IServiceProvider provider) { base.RemoveProperty(ListenActivity.IsListenTrigerredProperty); base.RemoveProperty(ListenActivity.ActivityStateProperty); } #region Dynamic Update Methods [NonSerialized] private bool activeBranchRemoved = false; protected override sealed void OnActivityChangeAdd(ActivityExecutionContext executionContext, Activity addedActivity) { if (executionContext == null) throw new ArgumentNullException("executionContext"); if (addedActivity == null) throw new ArgumentNullException("addedActivity"); Debug.Assert(addedActivity is EventDrivenActivity, "Listen only contains EventDriven activities"); ListenActivity listen = executionContext.Activity as ListenActivity; if (listen.ExecutionStatus == ActivityExecutionStatus.Executing && listen.ActivityState != null && !listen.IsListenTrigerred) { EventDrivenActivity eda = addedActivity as EventDrivenActivity; ListenEventActivitySubscriber eventActivitySubscriber = new ListenEventActivitySubscriber(eda); eda.EventActivity.Subscribe(executionContext, eventActivitySubscriber); listen.ActivityState.Insert(listen.EnabledActivities.IndexOf(addedActivity), eventActivitySubscriber); } } protected override sealed void OnActivityChangeRemove(ActivityExecutionContext executionContext, Activity removedActivity) { if (executionContext == null) throw new ArgumentNullException("executionContext"); if (removedActivity == null) throw new ArgumentNullException("removedActivity"); ListenActivity listen = executionContext.Activity as ListenActivity; if (listen.ExecutionStatus == ActivityExecutionStatus.Executing && listen.ActivityState != null && !listen.IsListenTrigerred) { EventDrivenActivity eda = removedActivity as EventDrivenActivity; for (int i = 0; i < listen.ActivityState.Count; ++i) { ListenEventActivitySubscriber listenEventSubscriber = listen.ActivityState[i]; if (listenEventSubscriber.eventDrivenActivity.QualifiedName.Equals(eda.QualifiedName)) { eda.EventActivity.Unsubscribe(executionContext, listenEventSubscriber); listen.ActivityState.RemoveAt(i); return; } } } else if (this.IsListenTrigerred && removedActivity.ExecutionStatus == ActivityExecutionStatus.Closed) { activeBranchRemoved = true; } } protected override void OnWorkflowChangesCompleted(ActivityExecutionContext executionContext) { base.OnWorkflowChangesCompleted(executionContext); if (activeBranchRemoved) executionContext.CloseActivity(); activeBranchRemoved = false; } #endregion #endregion #region Private Implementation #region Private Runtime State Dependency Properties static DependencyProperty IsListenTrigerredProperty = DependencyProperty.Register("IsListenTrigerred", typeof(bool), typeof(ListenActivity), new PropertyMetadata(false)); static DependencyProperty ActivityStateProperty = DependencyProperty.Register("ActivityState", typeof(List ), typeof(ListenActivity)); private bool IsListenTrigerred { get { return (bool)base.GetValue(IsListenTrigerredProperty); } set { base.SetValue(IsListenTrigerredProperty, value); } } private List ActivityState { get { return (List )base.GetValue(ActivityStateProperty); } set { if (value == null) base.RemoveProperty(ActivityStateProperty); else base.SetValue(ActivityStateProperty, value); } } #endregion #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"); e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this); context.CloseActivity(); } #endregion #region Subscription Datastructures [Serializable] private sealed class ListenEventActivitySubscriber : IActivityEventListener { internal EventDrivenActivity eventDrivenActivity; internal ListenEventActivitySubscriber(EventDrivenActivity eventDriven) { this.eventDrivenActivity = eventDriven; } 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(SR.Error_SenderMustBeActivityExecutionContext, "sender"); ListenActivity parentActivity = context.Activity as ListenActivity; if (!parentActivity.IsListenTrigerred && parentActivity.ExecutionStatus != ActivityExecutionStatus.Canceling && parentActivity.ExecutionStatus != ActivityExecutionStatus.Closed) { //Check whether it is still live in tree. if (!parentActivity.EnabledActivities.Contains(eventDrivenActivity))//Activity is dynamically removed. return; parentActivity.IsListenTrigerred = true; for (int i = 0; i < parentActivity.EnabledActivities.Count; ++i) { EventDrivenActivity eventDriven = parentActivity.EnabledActivities[i] as EventDrivenActivity; ListenEventActivitySubscriber eventSubscriber = parentActivity.ActivityState[i]; eventDriven.EventActivity.Unsubscribe(context, eventSubscriber); } eventDrivenActivity.RegisterForStatusChange(Activity.ClosedEvent, parentActivity); context.ExecuteActivity(eventDrivenActivity); } } } #endregion #endregion } #region Validator internal sealed class ListenValidator : CompositeActivityValidator { public override ValidationErrorCollection Validate(ValidationManager manager, object obj) { ValidationErrorCollection validationErrors = new ValidationErrorCollection(base.Validate(manager, obj)); ListenActivity listen = obj as ListenActivity; if (listen == null) throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(ListenActivity).FullName), "obj"); // Validate number of children if (listen.EnabledActivities.Count < 2) validationErrors.Add(new ValidationError(SR.GetString(SR.Error_ListenLessThanTwoChildren), ErrorNumbers.Error_ListenLessThanTwoChildren)); bool bNotAllEventDriven = false; foreach (Activity activity in listen.EnabledActivities) { if(!(activity is EventDrivenActivity)) bNotAllEventDriven = true; } // validate that all child activities are event driven activities. if(bNotAllEventDriven) validationErrors.Add(new ValidationError(SR.GetString(SR.Error_ListenNotAllEventDriven), ErrorNumbers.Error_ListenNotAllEventDriven)); return validationErrors; } } #endregion } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ActivityBuilderHelper.cs
- BindingGroup.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- DetailsViewDeleteEventArgs.cs
- QilSortKey.cs
- XPathNavigator.cs
- IsolationInterop.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- ListControl.cs
- ResourceAttributes.cs
- DataGridViewColumnStateChangedEventArgs.cs
- InternalMappingException.cs
- BitmapData.cs
- HistoryEventArgs.cs
- QilXmlWriter.cs
- Wizard.cs
- ISO2022Encoding.cs
- MergePropertyDescriptor.cs
- SelectingProviderEventArgs.cs
- DSASignatureFormatter.cs
- Positioning.cs
- SqlUserDefinedAggregateAttribute.cs
- WindowsFormsHostPropertyMap.cs
- QueryableDataSource.cs
- WorkflowMarkupSerializer.cs
- ProviderMetadataCachedInformation.cs
- EnvelopedSignatureTransform.cs
- GeneratedCodeAttribute.cs
- TranslateTransform3D.cs
- Transform3DGroup.cs
- ControlPropertyNameConverter.cs
- MetadataPropertyvalue.cs
- HtmlSelect.cs
- SqlAliasesReferenced.cs
- AutomationIdentifier.cs
- FontConverter.cs
- DocumentScope.cs
- LiteralControl.cs
- DispatcherExceptionEventArgs.cs
- Calendar.cs
- SpeakCompletedEventArgs.cs
- XamlTypeMapper.cs
- XPathCompileException.cs
- DynamicDataRouteHandler.cs
- FlowDocumentFormatter.cs
- Funcletizer.cs
- ImageButton.cs
- TemplateApplicationHelper.cs
- WebAdminConfigurationHelper.cs
- ChangeProcessor.cs
- BinaryParser.cs
- PrePostDescendentsWalker.cs
- WaitHandleCannotBeOpenedException.cs
- Symbol.cs
- ForeignKeyConstraint.cs
- ChildrenQuery.cs
- updateconfighost.cs
- CompoundFileDeflateTransform.cs
- PolicyManager.cs
- TextReader.cs
- SafePEFileHandle.cs
- Trigger.cs
- PathBox.cs
- ScriptingScriptResourceHandlerSection.cs
- ImageAttributes.cs
- XmlDigitalSignatureProcessor.cs
- IgnoreSectionHandler.cs
- TextRange.cs
- OleDbReferenceCollection.cs
- DataTemplateSelector.cs
- XmlSchemaAttribute.cs
- MouseOverProperty.cs
- SrgsToken.cs
- ZipArchive.cs
- TickBar.cs
- PaintEvent.cs
- EntityDataSourceWrapper.cs
- FormsAuthenticationCredentials.cs
- DesignTimeDataBinding.cs
- ByteStorage.cs
- CollectionBuilder.cs
- ToolBar.cs
- SystemException.cs
- RuntimeIdentifierPropertyAttribute.cs
- RunClient.cs
- ArraySortHelper.cs
- GCHandleCookieTable.cs
- RawStylusActions.cs
- WindowsStatusBar.cs
- DiagnosticsElement.cs
- AsmxEndpointPickerExtension.cs
- RepeaterCommandEventArgs.cs
- Tokenizer.cs
- BaseValidatorDesigner.cs
- Terminate.cs
- ListChangedEventArgs.cs
- ByteFacetDescriptionElement.cs
- IpcChannel.cs
- SqlDataSourceView.cs
- ExceptQueryOperator.cs