Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DynamicMethod.cs
- ClaimTypeRequirement.cs
- ListControl.cs
- GeometryValueSerializer.cs
- CatalogZoneBase.cs
- DependencyObject.cs
- MouseButton.cs
- SiteOfOriginPart.cs
- ADConnectionHelper.cs
- TextElement.cs
- NetSectionGroup.cs
- RegionData.cs
- SslStreamSecurityBindingElement.cs
- ToolStripDropTargetManager.cs
- CodeTypeReference.cs
- QilPatternFactory.cs
- ServiceBehaviorElement.cs
- ConnectionInterfaceCollection.cs
- DetailsViewDeletedEventArgs.cs
- OLEDB_Enum.cs
- ViewKeyConstraint.cs
- ExceptionCollection.cs
- BaseParagraph.cs
- ActivityExecutorSurrogate.cs
- TemplatePropertyEntry.cs
- EntityDataSourceWizardForm.cs
- OutputScopeManager.cs
- XsdDateTime.cs
- XmlSortKeyAccumulator.cs
- WorkflowStateRollbackService.cs
- HttpApplicationFactory.cs
- DBSchemaTable.cs
- HtmlHead.cs
- WindowProviderWrapper.cs
- NativeMethods.cs
- MailBnfHelper.cs
- DockPatternIdentifiers.cs
- SqlNamer.cs
- CursorConverter.cs
- documentation.cs
- Transform3D.cs
- ObjectDataSourceView.cs
- _ProxyRegBlob.cs
- XmlAnyElementAttribute.cs
- WmlControlAdapter.cs
- ImageField.cs
- SectionXmlInfo.cs
- GrammarBuilderRuleRef.cs
- SamlSecurityToken.cs
- StopStoryboard.cs
- QueryCreatedEventArgs.cs
- MetadataFile.cs
- RetrieveVirtualItemEventArgs.cs
- X509Extension.cs
- DataKeyCollection.cs
- EdmComplexPropertyAttribute.cs
- SystemNetworkInterface.cs
- DependencyPropertyDescriptor.cs
- Substitution.cs
- CustomSignedXml.cs
- EtwTrace.cs
- FlowNode.cs
- ToolBarDesigner.cs
- AnnotationElement.cs
- DbProviderManifest.cs
- Token.cs
- PrintPreviewDialog.cs
- FlowDocument.cs
- RSAPKCS1SignatureFormatter.cs
- MailAddress.cs
- PingReply.cs
- DiscreteKeyFrames.cs
- WebConfigurationFileMap.cs
- Lease.cs
- SkewTransform.cs
- DelimitedListTraceListener.cs
- ParsedAttributeCollection.cs
- LocalBuilder.cs
- SoapConverter.cs
- EditorPartCollection.cs
- Object.cs
- MemberHolder.cs
- GregorianCalendar.cs
- SoapTypeAttribute.cs
- CultureSpecificCharacterBufferRange.cs
- StickyNoteContentControl.cs
- ObjectViewListener.cs
- ParserContext.cs
- DefaultPropertyAttribute.cs
- SQLResource.cs
- WebPartZoneBase.cs
- DirectionalLight.cs
- SeparatorAutomationPeer.cs
- Brush.cs
- SurrogateEncoder.cs
- WindowHideOrCloseTracker.cs
- CancellationHandler.cs
- SQLSingleStorage.cs
- ImageSourceValueSerializer.cs
- BrowsableAttribute.cs