// Save the workflow instance state at the point of persistence with option of locking the instance state if it is shared // across multiple runtimes or multiple phase instance updates protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock) { // Save the workflow Guid contextGuid = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty); Console.WriteLine("Saving instance: {0}\n", contextGuid); SerializeToFile( WorkflowPersistenceService.GetDefaultSerializedForm(rootActivity), contextGuid); // See when the next timer (Delay activity) for this workflow will expire TimerEventSubscriptionCollection timers = (TimerEventSubscriptionCollection)rootActivity.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty); TimerEventSubscription subscription = timers.Peek(); if (subscription != null) { // Set a system timer to automatically reload this workflow when its next timer expires TimerCallback callback = new TimerCallback(ReloadWorkflow); TimeSpan timeDifference = subscription.ExpiresAt - DateTime.UtcNow; // check to make sure timeDifference is in legal range if (timeDifference > FilePersistenceService.MaxInterval) { timeDifference = FilePersistenceService.MaxInterval; } else if (timeDifference < TimeSpan.Zero) { timeDifference = TimeSpan.Zero; } this.instanceTimers.Add(contextGuid, new System.Threading.Timer( callback, subscription.WorkflowInstanceId, timeDifference, new TimeSpan(-1))); } }
public void Initialize(Activity definition, IDictionary <string, object> inputs, bool hasNameCollision) { this.rootActivity.SetValue(Activity.ActivityExecutionContextInfoProperty, new ActivityExecutionContextInfo(this.rootActivity.QualifiedName, this.GetNewContextActivityId(), instanceId, -1)); this.rootActivity.SetValue(Activity.ActivityContextGuidProperty, instanceId); SetInputParameters(definition, this.rootActivity, inputs, hasNameCollision); ((IDependencyObjectAccessor)this.rootActivity).InitializeActivatingInstanceForRuntime( null, this); this.rootActivity.FixUpMetaProperties(definition); TimerQueue = new TimerEventSubscriptionCollection(this, this.instanceId); using (new ServiceEnvironment(this.rootActivity)) { using (SetCurrentActivity(this.rootActivity)) { RegisterContextActivity(this.rootActivity); using (ActivityExecutionContext executionContext = new ActivityExecutionContext(this.rootActivity, true)) { executionContext.InitializeActivity(this.rootActivity); } } } }
void IEventActivity.Unsubscribe(ActivityExecutionContext parentContext, IActivityEventListener <QueueEventArgs> parentEventHandler) { if (parentContext == null) { throw new ArgumentNullException("parentContext"); } if (parentEventHandler == null) { throw new ArgumentNullException("parentEventHandler"); } System.Diagnostics.Debug.Assert(this.SubscriptionID != Guid.Empty); WorkflowQueuingService qService = parentContext.GetService <WorkflowQueuingService>(); WorkflowQueue wfQueue = null; try { wfQueue = qService.GetWorkflowQueue(this.SubscriptionID); } catch { // If the queue no longer exists, eat the exception, we clear the subscription id later. } if (wfQueue != null && wfQueue.Count != 0) { wfQueue.Dequeue(); } // WinOE Activity root = parentContext.Activity; while (root.Parent != null) { root = root.Parent; } TimerEventSubscriptionCollection timers = (TimerEventSubscriptionCollection)root.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty); Debug.Assert(timers != null, "TimerEventSubscriptionCollection on root activity should never be null, but it was"); timers.Remove(this.SubscriptionID); if (wfQueue != null) { wfQueue.UnregisterForQueueItemAvailable(parentEventHandler); qService.DeleteWorkflowQueue(this.SubscriptionID); } this.SubscriptionID = Guid.Empty; }
void IEventActivity.Subscribe(ActivityExecutionContext parentContext, IActivityEventListener <QueueEventArgs> parentEventHandler) { if (parentContext == null) { throw new ArgumentNullException("parentContext"); } if (parentEventHandler == null) { throw new ArgumentNullException("parentEventHandler"); } this.IsInEventActivityMode = true; base.RaiseEvent(DelayActivity.InitializeTimeoutDurationEvent, this, EventArgs.Empty); TimeSpan timeSpan = this.TimeoutDuration; DateTime timeOut = DateTime.UtcNow + timeSpan; WorkflowQueuingService qService = parentContext.GetService <WorkflowQueuingService>(); IComparable queueName = ((IEventActivity)this).QueueName; TimerEventSubscription timerSub = new TimerEventSubscription((Guid)queueName, this.WorkflowInstanceId, timeOut); WorkflowQueue queue = qService.CreateWorkflowQueue(queueName, false); queue.RegisterForQueueItemAvailable(parentEventHandler, this.QualifiedName); this.SubscriptionID = timerSub.SubscriptionId; Activity root = this; while (root.Parent != null) { root = root.Parent; } TimerEventSubscriptionCollection timers = (TimerEventSubscriptionCollection)root.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty); Debug.Assert(timers != null, "TimerEventSubscriptionCollection on root activity should never be null, but it was"); timers.Add(timerSub); }