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
- Converter.cs
- TdsValueSetter.cs
- AttachedPropertyBrowsableForChildrenAttribute.cs
- AssemblyCache.cs
- IriParsingElement.cs
- DataBindingCollection.cs
- X509UI.cs
- PolicyUnit.cs
- Int16KeyFrameCollection.cs
- GenericTypeParameterBuilder.cs
- SpecularMaterial.cs
- TokenBasedSetEnumerator.cs
- WebPartVerb.cs
- DataGridPageChangedEventArgs.cs
- EventArgs.cs
- SignatureToken.cs
- InternalMappingException.cs
- SqlClientFactory.cs
- DataContractJsonSerializerOperationBehavior.cs
- ExpressionHelper.cs
- ContentTextAutomationPeer.cs
- SoapSchemaMember.cs
- DBBindings.cs
- TextSchema.cs
- LogicalExpr.cs
- ProtectedConfiguration.cs
- PaintValueEventArgs.cs
- loginstatus.cs
- GuidelineSet.cs
- DbConnectionPoolOptions.cs
- RightsManagementPermission.cs
- ArrayWithOffset.cs
- SchemaEntity.cs
- ManagementOperationWatcher.cs
- Point3DAnimationUsingKeyFrames.cs
- RectangleF.cs
- GridErrorDlg.cs
- MimeFormatter.cs
- SHA384Managed.cs
- RevocationPoint.cs
- ObjectDataSourceMethodEventArgs.cs
- BrushValueSerializer.cs
- TagPrefixAttribute.cs
- BitmapEffectInputConnector.cs
- ExternalDataExchangeService.cs
- TextServicesCompartmentContext.cs
- HashAlgorithm.cs
- ReadOnlyMetadataCollection.cs
- RegexNode.cs
- XPathNodeInfoAtom.cs
- Comparer.cs
- LinkConverter.cs
- RangeValuePatternIdentifiers.cs
- HttpFormatExtensions.cs
- SmiMetaData.cs
- _HelperAsyncResults.cs
- CanonicalFormWriter.cs
- LocalFileSettingsProvider.cs
- ConnectionsZoneDesigner.cs
- ReflectPropertyDescriptor.cs
- DependencyProperty.cs
- TagPrefixCollection.cs
- FamilyTypeface.cs
- MaskInputRejectedEventArgs.cs
- RoleExceptions.cs
- Binding.cs
- PageParserFilter.cs
- MultiTrigger.cs
- ThrowHelper.cs
- BypassElementCollection.cs
- ConnectionsZoneDesigner.cs
- GridViewCommandEventArgs.cs
- ListViewTableRow.cs
- Vector3DAnimationUsingKeyFrames.cs
- PartialTrustVisibleAssembly.cs
- ExpressionStringBuilder.cs
- SkipQueryOptionExpression.cs
- WebReference.cs
- HistoryEventArgs.cs
- WebMessageEncodingBindingElement.cs
- ScriptManager.cs
- RegisteredDisposeScript.cs
- Baml2006KnownTypes.cs
- WindowsTooltip.cs
- __Error.cs
- ScrollBar.cs
- DesignTableCollection.cs
- RuleSettingsCollection.cs
- FixedElement.cs
- MultipartIdentifier.cs
- UTF32Encoding.cs
- XmlValidatingReaderImpl.cs
- CssStyleCollection.cs
- XmlTextReaderImplHelpers.cs
- WebPartTransformerAttribute.cs
- PropertyRecord.cs
- SelectionEditor.cs
- ListViewItemEventArgs.cs
- DataGridViewAccessibleObject.cs
- XhtmlBasicSelectionListAdapter.cs