Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / StateMachineSubscriptionManager.cs / 1305376 / StateMachineSubscriptionManager.cs
#region Using directives using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Reflection; using System.Diagnostics; using System.Runtime.Remoting.Messaging; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Workflow.Runtime.Hosting; #endregion Using directives namespace System.Workflow.Activities { [Serializable] internal class StateMachineSubscriptionManager { private SetStateSubscription _setStateSubscription; private List_eventQueue = new List (); private Dictionary _subscriptions = new Dictionary (); private StateMachineExecutionState _executionState; internal StateMachineSubscriptionManager(StateMachineExecutionState executionState, Guid instanceId) { _executionState = executionState; _setStateSubscription = new SetStateSubscription(instanceId); } #region Properties private List EventQueue { get { return this._eventQueue; } } internal StateMachineExecutionState ExecutionState { get { return _executionState; } } internal Dictionary Subscriptions { get { return this._subscriptions; } } internal SetStateSubscription SetStateSubscription { get { return _setStateSubscription; } } #endregion Properties internal void UnsubscribeState(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; foreach (Activity childActivity in state.EnabledActivities) { EventDrivenActivity eventDriven = childActivity as EventDrivenActivity; if (eventDriven != null) { if (IsEventDrivenSubscribed(eventDriven)) UnsubscribeEventDriven(context, eventDriven); } } } internal void ReevaluateSubscriptions(ActivityExecutionContext context) { Dictionary subscriptions = this.GetSubscriptionsShallowCopy(); List subscribed = new List (); StateActivity state = StateMachineHelpers.GetCurrentState(context); while (state != null) { foreach (Activity activity in state.EnabledActivities) { EventDrivenActivity eventDriven = activity as EventDrivenActivity; if (eventDriven == null) continue; IEventActivity eventActivity = StateMachineHelpers.GetEventActivity(eventDriven); IComparable queueName = eventActivity.QueueName; if (queueName == null) continue; StateMachineSubscription subscription; subscriptions.TryGetValue(queueName, out subscription); EventActivitySubscription eventActivitySubscription = subscription as EventActivitySubscription; if (eventActivitySubscription != null) { if (eventActivitySubscription.EventDrivenName.Equals(eventDriven.QualifiedName)) { // this EventDriven is already subscribed subscribed.Add(queueName); continue; } else { // Check if this state already subscribe to this event // if so, throws, since it is not valid to subscribe to the // same event twice if (eventActivitySubscription.StateName.Equals(state.QualifiedName)) throw new InvalidOperationException(SR.GetStateAlreadySubscribesToThisEvent(state.QualifiedName, queueName)); // some other EventDriven is subscribed, so we need to unsubscribe if // the event driven belongs to one of our parents if (IsParentState(state, eventActivitySubscription.StateName)) { UnsubscribeAction unsubscribe = new UnsubscribeAction(eventActivitySubscription.StateName, eventActivitySubscription.EventDrivenName); this.ExecutionState.EnqueueAction(unsubscribe); subscriptions.Remove(queueName); } } } // Tests if a child state already subscribes to this event // is so, skip, since the child takes precedence if (subscribed.Contains(queueName)) continue; SubscribeAction subscribe = new SubscribeAction(state.QualifiedName, eventDriven.QualifiedName); this.ExecutionState.EnqueueAction(subscribe); subscribed.Add(queueName); } state = state.Parent as StateActivity; } StateActivity currentState = StateMachineHelpers.GetCurrentState(context); DisableQueuesAction disableQueues = new DisableQueuesAction(currentState.QualifiedName); this.ExecutionState.EnqueueAction(disableQueues); } private bool IsParentState(StateActivity state, string stateName) { StateActivity parentState = state.Parent as StateActivity; while (parentState != null) { if (parentState.QualifiedName.Equals(stateName)) return true; parentState = parentState.Parent as StateActivity; } return false; } internal void SubscribeEventDriven(ActivityExecutionContext context, EventDrivenActivity eventDriven) { IEventActivity eventActivity = StateMachineHelpers.GetEventActivity(eventDriven); Activity activity = (Activity)eventActivity; IComparable queueName = GetQueueName(eventActivity); Debug.Assert(!this.Subscriptions.ContainsKey(queueName)); SubscribeEventActivity(context, eventActivity); } internal void UnsubscribeEventDriven(ActivityExecutionContext context, EventDrivenActivity eventDriven) { Debug.Assert(IsEventDrivenSubscribed(eventDriven)); IEventActivity eventActivity = StateMachineHelpers.GetEventActivity(eventDriven); UnsubscribeEventActivity(context, eventActivity); } private StateMachineSubscription SubscribeEventActivity(ActivityExecutionContext context, IEventActivity eventActivity) { EventActivitySubscription subscription = new EventActivitySubscription(); StateActivity state = (StateActivity)context.Activity; subscription.Subscribe(context, state, eventActivity); WorkflowQueue workflowQueue = GetWorkflowQueue(context, subscription.QueueName); if (workflowQueue != null) workflowQueue.Enabled = true; Debug.Assert(subscription.QueueName != null); this.Subscriptions[subscription.QueueName] = subscription; return subscription; } private void UnsubscribeEventActivity(ActivityExecutionContext context, IEventActivity eventActivity) { if (context == null) throw new ArgumentNullException("context"); if (eventActivity == null) throw new ArgumentNullException("eventActivity"); EventActivitySubscription subscription = GetSubscription(eventActivity); WorkflowQueue workflowQueue = GetWorkflowQueue(context, subscription.QueueName); if (workflowQueue != null) workflowQueue.Enabled = false; UnsubscribeEventActivity(context, eventActivity, subscription); } private void UnsubscribeEventActivity(ActivityExecutionContext context, IEventActivity eventActivity, EventActivitySubscription subscription) { if (context == null) throw new ArgumentNullException("context"); if (eventActivity == null) throw new ArgumentNullException("eventActivity"); if (subscription == null) throw new ArgumentNullException("subscription"); subscription.Unsubscribe(context, eventActivity); RemoveFromQueue(subscription.SubscriptionId); Debug.Assert(subscription.QueueName != null); this.Subscriptions.Remove(subscription.QueueName); } internal void CreateSetStateEventQueue(ActivityExecutionContext context) { this.SetStateSubscription.CreateQueue(context); this.Subscriptions[this.SetStateSubscription.SubscriptionId] = this.SetStateSubscription; } internal void DeleteSetStateEventQueue(ActivityExecutionContext context) { this.Subscriptions[this.SetStateSubscription.SubscriptionId] = null; this.SetStateSubscription.DeleteQueue(context); } internal void SubscribeToSetStateEvent(ActivityExecutionContext context) { this.SetStateSubscription.Subscribe(context); this.Subscriptions[this.SetStateSubscription.SubscriptionId] = this.SetStateSubscription; } internal void UnsubscribeToSetStateEvent(ActivityExecutionContext context) { this.Subscriptions[this.SetStateSubscription.SubscriptionId] = null; this.SetStateSubscription.Unsubscribe(context); } private bool IsEventDrivenSubscribed(EventDrivenActivity eventDriven) { IEventActivity eventActivity = StateMachineHelpers.GetEventActivity(eventDriven); EventActivitySubscription subscription = GetSubscription(eventActivity); return (subscription != null); } private EventActivitySubscription GetSubscription(IEventActivity eventActivity) { IComparable queueName = GetQueueName(eventActivity); if ((queueName == null) || (!this.Subscriptions.ContainsKey(queueName))) return null; EventActivitySubscription subscription = this.Subscriptions[queueName] as EventActivitySubscription; Activity activity = (Activity)eventActivity; if (subscription == null || subscription.EventActivityName != activity.QualifiedName) return null; return subscription; } private StateMachineSubscription GetSubscription(IComparable queueName) { StateMachineSubscription subscription; this.Subscriptions.TryGetValue(queueName, out subscription); return subscription; } /* Currently not used, left here for completeness internal static void EnableStateWorkflowQueues(ActivityExecutionContext context, StateActivity state) { ChangeStateWorkflowQueuesState(context, state, true); } */ internal static void DisableStateWorkflowQueues(ActivityExecutionContext context, StateActivity state) { ChangeStateWorkflowQueuesState(context, state, false); } private static void ChangeStateWorkflowQueuesState(ActivityExecutionContext context, StateActivity state, bool enabled) { foreach (Activity activity in state.EnabledActivities) { EventDrivenActivity eventDriven = activity as EventDrivenActivity; if (eventDriven != null) ChangeEventDrivenQueueState(context, eventDriven, enabled); } } internal static void ChangeEventDrivenQueueState(ActivityExecutionContext context, EventDrivenActivity eventDriven, bool enabled) { IEventActivity eventActivity = StateMachineHelpers.GetEventActivity(eventDriven); IComparable queueName = GetQueueName(eventActivity); if (queueName == null) return; // skip unitialized follower WorkflowQueue workflowQueue = GetWorkflowQueue(context, queueName); if (workflowQueue != null) workflowQueue.Enabled = enabled; } internal static WorkflowQueue GetWorkflowQueue(ActivityExecutionContext context, IComparable queueName) { WorkflowQueuingService workflowQueuingService = context.GetService (); if (workflowQueuingService.Exists(queueName)) { WorkflowQueue workflowQueue = workflowQueuingService.GetWorkflowQueue(queueName); return workflowQueue; } return null; } private static IComparable GetQueueName(IEventActivity eventActivity) { IComparable queueName = eventActivity.QueueName; return queueName; } private Dictionary GetSubscriptionsShallowCopy() { Dictionary subscriptions = new Dictionary (); foreach (KeyValuePair dictionaryEntry in this.Subscriptions) { subscriptions.Add(dictionaryEntry.Key, dictionaryEntry.Value); } return subscriptions; } #region Event Queue Methods internal void Enqueue(ActivityExecutionContext context, Guid subscriptionId) { StateMachineSubscription subscription = GetSubscription(subscriptionId); if (subscription != null) { // subscription can be null if we already unsubscribed to // this event this.EventQueue.Add(subscription); } ProcessQueue(context); } internal void Enqueue(ActivityExecutionContext context, IComparable queueName) { StateMachineSubscription subscription = GetSubscription(queueName); if (subscription != null) { // subscription can be null if we already unsubscribed to // this event this.EventQueue.Add(subscription); } ProcessQueue(context); } internal StateMachineSubscription Dequeue() { StateMachineSubscription subscription = this.EventQueue[0]; this.EventQueue.RemoveAt(0); return subscription; } private void RemoveFromQueue(Guid subscriptionId) { this.EventQueue.RemoveAll(delegate(StateMachineSubscription subscription) { return subscription.SubscriptionId.Equals(subscriptionId); }); } internal void ProcessQueue(ActivityExecutionContext context) { StateActivity currentState = StateMachineHelpers.GetCurrentState(context); if (this.EventQueue.Count == 0 || this.ExecutionState.HasEnqueuedActions || this.ExecutionState.SchedulerBusy || currentState == null) return; StateMachineSubscription subscription = Dequeue(); subscription.ProcessEvent(context); } #endregion Event Queue Methods } } // 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
- FileDialogPermission.cs
- UserNameSecurityTokenProvider.cs
- XmlDownloadManager.cs
- VersionedStream.cs
- GlobalAllocSafeHandle.cs
- MetadataArtifactLoader.cs
- ControlBindingsCollection.cs
- CatalogZone.cs
- WmlCommandAdapter.cs
- ErrorView.xaml.cs
- KeyFrames.cs
- XmlSchemaAttributeGroup.cs
- SqlReorderer.cs
- RelationalExpressions.cs
- BinaryUtilClasses.cs
- NativeMethods.cs
- RequestBringIntoViewEventArgs.cs
- TextEvent.cs
- PersonalizationProviderCollection.cs
- UnwrappedTypesXmlSerializerManager.cs
- StorageMappingFragment.cs
- Part.cs
- LogSwitch.cs
- RemotingSurrogateSelector.cs
- XmlBufferReader.cs
- ComplusTypeValidator.cs
- EntityContainerEntitySet.cs
- ChtmlTextWriter.cs
- SqlConnectionHelper.cs
- SchemaDeclBase.cs
- XPathNode.cs
- FunctionQuery.cs
- LicenseContext.cs
- SystemIcmpV6Statistics.cs
- GridEntryCollection.cs
- RemoteWebConfigurationHostStream.cs
- PhysicalAddress.cs
- SerializableTypeCodeDomSerializer.cs
- StreamResourceInfo.cs
- PeerSecurityManager.cs
- Trace.cs
- MethodBody.cs
- XmlSchemaExternal.cs
- SapiGrammar.cs
- WebPartMenuStyle.cs
- BoundColumn.cs
- ResXResourceWriter.cs
- BufferAllocator.cs
- TypedRowGenerator.cs
- ContainerUIElement3D.cs
- StackOverflowException.cs
- EnglishPluralizationService.cs
- OdbcParameter.cs
- HttpHandlersSection.cs
- TypeReference.cs
- XmlSchemaComplexContentExtension.cs
- IndicCharClassifier.cs
- SkipStoryboardToFill.cs
- ConsoleKeyInfo.cs
- HttpPostedFile.cs
- CardSpaceException.cs
- XmlSchemaExternal.cs
- MDIControlStrip.cs
- ToolStripItemEventArgs.cs
- ListCollectionView.cs
- MarginsConverter.cs
- ExecutionProperties.cs
- RegisteredDisposeScript.cs
- FormViewUpdatedEventArgs.cs
- ErrorsHelper.cs
- EditorZone.cs
- FullTrustAssemblyCollection.cs
- ProxyGenerator.cs
- UnsafeNativeMethods.cs
- XamlSerializer.cs
- Pen.cs
- Inline.cs
- SerializationAttributes.cs
- HMAC.cs
- Int16Storage.cs
- CqlGenerator.cs
- XmlnsDefinitionAttribute.cs
- PickBranch.cs
- CultureTableRecord.cs
- ListBindingConverter.cs
- ApplicationFileParser.cs
- Pens.cs
- GeneralTransform3DGroup.cs
- TemplatePartAttribute.cs
- HiddenField.cs
- SqlParameter.cs
- TranslateTransform.cs
- SqlWebEventProvider.cs
- ResourcesChangeInfo.cs
- AspNetCompatibilityRequirementsAttribute.cs
- OleDbParameterCollection.cs
- RegexTree.cs
- TableRowCollection.cs
- XmlQueryContext.cs
- WorkflowQueueInfo.cs