internal void RevertToCheckpointState() { Activity rootActivity = null; this.clonedInstanceStateStream.Position = 0L; using (new RuntimeEnvironment(this.workflowExecutor.WorkflowRuntime)) { rootActivity = Activity.Load(this.clonedInstanceStateStream, this.workflowDefinition); } rootActivity.SetValue(WorkflowExecutor.TrackingListenerBrokerProperty, this.workflowExecutor.RootActivity.GetValue(WorkflowExecutor.TrackingListenerBrokerProperty)); WorkflowExecutor newWorkflowExecutor = new WorkflowExecutor(Guid.Empty); newWorkflowExecutor.Initialize(rootActivity, this.workflowExecutor.WorkflowRuntime, this.workflowExecutor); Activity contextActivityForId = newWorkflowExecutor.GetContextActivityForId(this.activityContextId); Activity activityByName = contextActivityForId.GetActivityByName(this.activityQualifiedName); using (new ServiceEnvironment(activityByName)) { using (newWorkflowExecutor.SetCurrentActivity(activityByName)) { using (ActivityExecutionContext context = new ActivityExecutionContext(activityByName)) { context.Invoke <EventArgs>(this.callbackHandler, this.callbackData); } } } newWorkflowExecutor.BatchCollection.WorkItemOrderId = this.workflowExecutor.BatchCollection.WorkItemOrderId; foreach (KeyValuePair <object, WorkBatch> pair in this.workflowExecutor.BatchCollection) { pair.Value.SetWorkBatchCollection(newWorkflowExecutor.BatchCollection); Activity key = pair.Key as Activity; if (key != null) { Activity activity5 = contextActivityForId.GetActivityByName(key.QualifiedName); newWorkflowExecutor.BatchCollection.Add(activity5, pair.Value); } } this.workflowExecutor.BatchCollection.Clear(); newWorkflowExecutor.CompletedContextActivities = this.completedContextActivities; this.workflowExecutor.WorkflowRuntime.ReplaceWorkflowExecutor(this.workflowExecutor.InstanceId, this.workflowExecutor, newWorkflowExecutor); if (!this.suspendOnRevert) { newWorkflowExecutor.Scheduler.Resume(); } else { newWorkflowExecutor.SuspendOnIdle(this.suspendOnRevertInfo); } this.DisposeCheckpointState(); }
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(); }