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
- ChangeInterceptorAttribute.cs
- SqlUserDefinedTypeAttribute.cs
- AsyncWaitHandle.cs
- MatrixCamera.cs
- _ContextAwareResult.cs
- GeneralTransform3DCollection.cs
- SynchronousChannel.cs
- ParserExtension.cs
- PersistenceContext.cs
- PersonalizableTypeEntry.cs
- ProtectedProviderSettings.cs
- SQLBinary.cs
- ApplicationId.cs
- HttpResponse.cs
- RequestQueryProcessor.cs
- ClipboardData.cs
- PropertyBuilder.cs
- IdnMapping.cs
- HttpHandler.cs
- UInt64Converter.cs
- KoreanLunisolarCalendar.cs
- ViewSimplifier.cs
- DbDataAdapter.cs
- PageDeviceFont.cs
- Int64Storage.cs
- SqlConnection.cs
- RequestResizeEvent.cs
- InternalTypeHelper.cs
- ButtonBaseDesigner.cs
- ProtocolReflector.cs
- QueryStringParameter.cs
- IdnMapping.cs
- PenCursorManager.cs
- MenuItemStyleCollection.cs
- SimpleApplicationHost.cs
- OLEDB_Enum.cs
- ToolTipAutomationPeer.cs
- AssemblyAssociatedContentFileAttribute.cs
- SoapProtocolImporter.cs
- ProfilePropertyMetadata.cs
- LinearQuaternionKeyFrame.cs
- EncryptedKeyIdentifierClause.cs
- SqlColumnizer.cs
- _Semaphore.cs
- BinaryNode.cs
- DocumentViewerBaseAutomationPeer.cs
- CodeNamespaceCollection.cs
- CommandDevice.cs
- ScrollChangedEventArgs.cs
- LabelDesigner.cs
- StyleHelper.cs
- ActiveXContainer.cs
- HtmlGenericControl.cs
- AggregateNode.cs
- OpenFileDialog.cs
- DiagnosticSection.cs
- XmlSchemaComplexContentExtension.cs
- DataGridViewColumn.cs
- EditorAttribute.cs
- TimeoutStream.cs
- ExternalException.cs
- ComponentManagerBroker.cs
- BasePropertyDescriptor.cs
- StorageEndPropertyMapping.cs
- DataComponentGenerator.cs
- SqlCacheDependencyDatabaseCollection.cs
- DocumentViewerAutomationPeer.cs
- RemotingConfiguration.cs
- Activation.cs
- ConfigurationSettings.cs
- X509Utils.cs
- TextTabProperties.cs
- SingleTagSectionHandler.cs
- OdbcTransaction.cs
- WebBrowser.cs
- ContentElement.cs
- AnimatedTypeHelpers.cs
- DependencyPropertyKind.cs
- COM2Properties.cs
- WebPartDisplayModeCancelEventArgs.cs
- BamlLocalizableResourceKey.cs
- lengthconverter.cs
- FloaterBaseParagraph.cs
- EntityContainerAssociationSet.cs
- Bits.cs
- pingexception.cs
- DataServiceQueryContinuation.cs
- XmlSignatureManifest.cs
- PingReply.cs
- DataControlLinkButton.cs
- UInt16Converter.cs
- SafeSecurityHandles.cs
- OdbcCommand.cs
- EpmSourcePathSegment.cs
- CallbackValidator.cs
- FixedHighlight.cs
- DataListCommandEventArgs.cs
- HostedTransportConfigurationBase.cs
- ClickablePoint.cs
- securitymgrsite.cs