internal void RevertToCheckpointState()
        {
            Debug.Assert(this.clonedInstanceStateStream != null, "cloned instance-state stream null at restore time");

            // deserialize only on first access
            Activity clonedRootActivity = null;
            this.clonedInstanceStateStream.Position = 0;
            using (RuntimeEnvironment runtimeEnv = new RuntimeEnvironment(this.workflowExecutor.WorkflowRuntime))
            {
                clonedRootActivity = Activity.Load(this.clonedInstanceStateStream, (Activity)this.workflowDefinition);
            }
            Debug.Assert(clonedRootActivity != null);
            //
            // Set the trackingListenerBroker before initializing the executor so the tracking
            // runtime gets a reference to the correct object
            clonedRootActivity.SetValue(WorkflowExecutor.TrackingListenerBrokerProperty, workflowExecutor.RootActivity.GetValue(WorkflowExecutor.TrackingListenerBrokerProperty));

            // create the new workflowExecutor
            WorkflowExecutor newWorkflowExecutor = new WorkflowExecutor(Guid.Empty);    // use a dummy guid while swapping executors
            newWorkflowExecutor.Initialize(clonedRootActivity, this.workflowExecutor.WorkflowRuntime, this.workflowExecutor);

            // enqueue the activity notifier
            Activity activityContext = newWorkflowExecutor.GetContextActivityForId(this.activityContextId);
            Activity activity = activityContext.GetActivityByName(this.activityQualifiedName);
            using (new ServiceEnvironment(activity))
            {
                using (newWorkflowExecutor.SetCurrentActivity(activity))
                {
                    using (ActivityExecutionContext executionContext = new ActivityExecutionContext(activity))
                        executionContext.Invoke<EventArgs>(this.callbackHandler, this.callbackData);
                }
            }
            //
            // Push the batch item ordering id to the new instance
            newWorkflowExecutor.BatchCollection.WorkItemOrderId = this.workflowExecutor.BatchCollection.WorkItemOrderId;
            // replace pending batch items
            foreach (KeyValuePair<object, WorkBatch> batch in this.workflowExecutor.BatchCollection)
            {
                batch.Value.SetWorkBatchCollection(newWorkflowExecutor.BatchCollection);
                Activity oldActivity = batch.Key as Activity;
                // no need to add the transient state batch
                if (oldActivity != null)
                {
                    Activity newactivity = activityContext.GetActivityByName(oldActivity.QualifiedName);
                    newWorkflowExecutor.BatchCollection.Add(newactivity, batch.Value);
                }
            }
            this.workflowExecutor.BatchCollection.Clear();

            Debug.Assert(this.completedContextActivities != null);
            newWorkflowExecutor.CompletedContextActivities = this.completedContextActivities;

            // replace with the WorkflowRuntime
            Debug.Assert(this.workflowExecutor.IsInstanceValid);
            this.workflowExecutor.WorkflowRuntime.ReplaceWorkflowExecutor(this.workflowExecutor.InstanceId, this.workflowExecutor, newWorkflowExecutor);

            // now resume or suspend the scheduler as needed
            if (!this.suspendOnRevert)
            {
                // get the new one going
                newWorkflowExecutor.Scheduler.Resume();
            }
            else
            {
                // this call will be old scheduler's thread
                newWorkflowExecutor.SuspendOnIdle(this.suspendOnRevertInfo);
            }
            DisposeCheckpointState();
        }
示例#2
0
        Activity IWorkflowCoreRuntime.LoadContextActivity(ActivityExecutionContextInfo contextInfo, Activity outerActivity)
        {
            if (!ServiceEnvironment.IsInServiceThread(this.InstanceId))
                throw new InvalidOperationException(ExecutionStringManager.MustUseRuntimeThread);
            Activity contextActivity = null;
            if (this.completedContextActivities.Contains(contextInfo))
            {
                contextActivity = (Activity)this.completedContextActivities[contextInfo];
                this.completedContextActivities.Remove(contextInfo);

                if (contextActivity.Parent != outerActivity.Parent)
                    contextActivity.parent = outerActivity.Parent;
            }
            else
            {
                using (RuntimeEnvironment runtimeEnv = new RuntimeEnvironment(this.WorkflowRuntime))
                {
                    contextActivity = this.WorkflowRuntime.WorkflowPersistenceService.LoadCompletedContextActivity(contextInfo.ContextGuid, outerActivity);
                    if (contextActivity == null)
                        throw new InvalidOperationException(ExecutionStringManager.LoadContextActivityFailed);
                }
            }
            return contextActivity;
        }
        internal void RevertToCheckpointState()
        {
            Debug.Assert(this.clonedInstanceStateStream != null, "cloned instance-state stream null at restore time");

            // deserialize only on first access
            Activity clonedRootActivity = null;

            this.clonedInstanceStateStream.Position = 0;
            using (RuntimeEnvironment runtimeEnv = new RuntimeEnvironment(this.workflowExecutor.WorkflowRuntime))
            {
                clonedRootActivity = Activity.Load(this.clonedInstanceStateStream, (Activity)this.workflowDefinition);
            }
            Debug.Assert(clonedRootActivity != null);
            //
            // Set the trackingListenerBroker before initializing the executor so the tracking
            // runtime gets a reference to the correct object
            clonedRootActivity.SetValue(WorkflowExecutor.TrackingListenerBrokerProperty, workflowExecutor.RootActivity.GetValue(WorkflowExecutor.TrackingListenerBrokerProperty));

            // create the new workflowExecutor
            WorkflowExecutor newWorkflowExecutor = new WorkflowExecutor(Guid.Empty);    // use a dummy guid while swapping executors

            newWorkflowExecutor.Initialize(clonedRootActivity, this.workflowExecutor.WorkflowRuntime, this.workflowExecutor);

            // enqueue the activity notifier
            Activity activityContext = newWorkflowExecutor.GetContextActivityForId(this.activityContextId);
            Activity activity        = activityContext.GetActivityByName(this.activityQualifiedName);

            using (new ServiceEnvironment(activity))
            {
                using (newWorkflowExecutor.SetCurrentActivity(activity))
                {
                    using (ActivityExecutionContext executionContext = new ActivityExecutionContext(activity))
                        executionContext.Invoke <EventArgs>(this.callbackHandler, this.callbackData);
                }
            }
            //
            // Push the batch item ordering id to the new instance
            newWorkflowExecutor.BatchCollection.WorkItemOrderId = this.workflowExecutor.BatchCollection.WorkItemOrderId;
            // replace pending batch items
            foreach (KeyValuePair <object, WorkBatch> batch in this.workflowExecutor.BatchCollection)
            {
                batch.Value.SetWorkBatchCollection(newWorkflowExecutor.BatchCollection);
                Activity oldActivity = batch.Key as Activity;
                // no need to add the transient state batch
                if (oldActivity != null)
                {
                    Activity newactivity = activityContext.GetActivityByName(oldActivity.QualifiedName);
                    newWorkflowExecutor.BatchCollection.Add(newactivity, batch.Value);
                }
            }
            this.workflowExecutor.BatchCollection.Clear();

            Debug.Assert(this.completedContextActivities != null);
            newWorkflowExecutor.CompletedContextActivities = this.completedContextActivities;

            // replace with the WorkflowRuntime
            Debug.Assert(this.workflowExecutor.IsInstanceValid);
            this.workflowExecutor.WorkflowRuntime.ReplaceWorkflowExecutor(this.workflowExecutor.InstanceId, this.workflowExecutor, newWorkflowExecutor);

            // now resume or suspend the scheduler as needed
            if (!this.suspendOnRevert)
            {
                // get the new one going
                newWorkflowExecutor.Scheduler.Resume();
            }
            else
            {
                // this call will be old scheduler's thread
                newWorkflowExecutor.SuspendOnIdle(this.suspendOnRevertInfo);
            }
            DisposeCheckpointState();
        }