Esempio n. 1
0
        protected internal override ValidationErrorCollection ValidateChanges(Activity contextActivity)
        {
            if (contextActivity == null)
            {
                throw new ArgumentNullException("contextActivity");
            }

            ValidationErrorCollection errors = new ValidationErrorCollection();

            CompositeActivity ownerActivity = contextActivity.TraverseDottedPathFromRoot(this.OwnerActivityDottedPath) as CompositeActivity;

            if (ownerActivity != null && WorkflowChanges.IsActivityExecutable(ownerActivity))
            {
                foreach (Validator validator in ComponentDispenser.CreateComponents(ownerActivity.GetType(), typeof(ActivityValidatorAttribute)))
                {
                    ValidationError error = validator.ValidateActivityChange(ownerActivity, this);
                    if (error != null)
                    {
                        errors.Add(error);
                    }
                }
            }

            return(errors);
        }
Esempio n. 2
0
        private void NotifyChangesCompletedToChildExecutors(IWorkflowCoreRuntime workflowCoreRuntime, Activity contextActivity)
        {
            Queue compositeActivities = new Queue();

            compositeActivities.Enqueue(contextActivity);
            while (compositeActivities.Count > 0)
            {
                CompositeActivity compositeActivity = compositeActivities.Dequeue() as CompositeActivity;
                if (compositeActivity == null || !WorkflowChanges.IsActivityExecutable(compositeActivity))
                {
                    continue;
                }

                ISupportWorkflowChanges compositeActivityExecutor = ActivityExecutors.GetActivityExecutor(compositeActivity) as ISupportWorkflowChanges;
                if (compositeActivityExecutor != null)
                {
                    using (workflowCoreRuntime.SetCurrentActivity(compositeActivity))
                    {
                        using (ActivityExecutionContext executionContext = new ActivityExecutionContext(compositeActivity))
                            compositeActivityExecutor.OnWorkflowChangesCompleted(executionContext);
                    }
                }
                foreach (Activity activity in compositeActivity.Activities)
                {
                    if (activity is CompositeActivity)
                    {
                        compositeActivities.Enqueue(activity);
                    }
                }
            }
        }
Esempio n. 3
0
        private void OnAddApprovalStep(object sender, EventArgs e)
        {
            InvokeWorkflowActivity invokeApprovalStepWorkflow = new InvokeWorkflowActivity();

            //
            // use WorkflowChanges class to author dynamic change
            //
            WorkflowChanges changes = new WorkflowChanges(this);
            //
            // setup to invoke ApprovalStepWorkflow type
            Type type = typeof(ApprovalStepWorkflow);
            invokeApprovalStepWorkflow.Name = "AddApprovalStepWorkflow";
            invokeApprovalStepWorkflow.TargetWorkflow = type;
            //
            // insert invokeApprovalStepWorkflow in ifElseApproval transient activity collection
            //
            CompositeActivity checkApproval = changes.TransientWorkflow.Activities["CheckApproval"] as CompositeActivity;
            CompositeActivity approvedBranch = checkApproval.Activities["Approved"] as CompositeActivity;
            approvedBranch.Activities.Add(invokeApprovalStepWorkflow);
            //
            // apply transient changes to instance
            //
            this.ApplyWorkflowChanges(changes);
            Console.WriteLine("  Added an InvokeWorkflow activity within the workflow to approve the PO");
         }
 public void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
 {
     using (new WorkflowTraceTransfer(this.InstanceId))
     {
         WorkflowExecutor executor;
     Label_000C:
         executor = this._runtime.Load(this);
         if (!executor.IsInstanceValid)
         {
             goto Label_000C;
         }
         try
         {
             executor.ApplyWorkflowChanges(workflowChanges);
         }
         catch (InvalidOperationException)
         {
             if (executor.IsInstanceValid)
             {
                 throw;
             }
             goto Label_000C;
         }
     }
 }
Esempio n. 5
0
        protected internal override ValidationErrorCollection ValidateChanges(Activity contextActivity)
        {
            ValidationErrorCollection errors  = base.ValidateChanges(contextActivity);
            Activity removedActivityInContext = contextActivity.TraverseDottedPathFromRoot(this.originalRemovedActivity.DottedPath);

            if (WorkflowChanges.IsActivityExecutable(removedActivityInContext) && removedActivityInContext.ExecutionStatus == ActivityExecutionStatus.Executing)
            {
                errors.Add(new ValidationError(SR.GetString(SR.Error_RemoveExecutingActivity, this.originalRemovedActivity.QualifiedName), ErrorNumbers.Error_RemoveExecutingActivity));
            }
            return(errors);
        }
Esempio n. 6
0
        protected internal override ValidationErrorCollection ValidateChanges(Activity contextActivity)
        {
            ValidationErrorCollection errors = base.ValidateChanges(contextActivity);
            Activity activity = contextActivity.TraverseDottedPathFromRoot(this.originalRemovedActivity.DottedPath);

            if (WorkflowChanges.IsActivityExecutable(activity) && (activity.ExecutionStatus == ActivityExecutionStatus.Executing))
            {
                errors.Add(new ValidationError(SR.GetString("Error_RemoveExecutingActivity", new object[] { this.originalRemovedActivity.QualifiedName }), 0x11d));
            }
            return(errors);
        }
Esempio n. 7
0
        private void NotifyChangesToChildExecutors(IWorkflowCoreRuntime workflowCoreRuntime, Activity contextActivity, IList <WorkflowChangeAction> changeActions)
        {
            foreach (WorkflowChangeAction action in changeActions)
            {
                if (!(action is ActivityChangeAction))
                {
                    continue;
                }

                CompositeActivity ownerActivity = contextActivity.TraverseDottedPathFromRoot(((ActivityChangeAction)action).OwnerActivityDottedPath) as CompositeActivity;
                if (ownerActivity == null || !WorkflowChanges.IsActivityExecutable(ownerActivity))
                {
                    continue;
                }

                ISupportWorkflowChanges compositeActivityExecutor = ActivityExecutors.GetActivityExecutor(ownerActivity) as ISupportWorkflowChanges;
                if (compositeActivityExecutor == null)
                {
                    throw new ApplicationException(SR.GetString(SR.Error_WorkflowChangesNotSupported, ownerActivity.GetType().FullName));
                }

                using (workflowCoreRuntime.SetCurrentActivity(ownerActivity))
                {
                    using (ActivityExecutionContext executionContext = new ActivityExecutionContext(ownerActivity))
                    {
                        if (action is AddedActivityAction)
                        {
                            Activity addedActivity = ownerActivity.Activities[((AddedActivityAction)action).Index];
                            if (WorkflowChanges.IsActivityExecutable(addedActivity))
                            {
                                addedActivity.OnActivityExecutionContextLoad(executionContext.Activity.RootActivity.WorkflowCoreRuntime);
                                executionContext.InitializeActivity(addedActivity);
                                compositeActivityExecutor.OnActivityAdded(executionContext, addedActivity);
                            }
                        }
                        else if (action is RemovedActivityAction)
                        {
                            RemovedActivityAction removedActivityAction = (RemovedActivityAction)action;
                            if (WorkflowChanges.IsActivityExecutable(removedActivityAction.OriginalRemovedActivity))
                            {
                                compositeActivityExecutor.OnActivityRemoved(executionContext, removedActivityAction.OriginalRemovedActivity);
                                if (removedActivityAction.OriginalRemovedActivity.ExecutionResult != ActivityExecutionResult.Uninitialized)
                                {
                                    removedActivityAction.OriginalRemovedActivity.Uninitialize(executionContext.Activity.RootActivity.WorkflowCoreRuntime);
                                    removedActivityAction.OriginalRemovedActivity.SetValue(Activity.ExecutionResultProperty, ActivityExecutionResult.Uninitialized);
                                }
                                removedActivityAction.OriginalRemovedActivity.OnActivityExecutionContextUnload(executionContext.Activity.RootActivity.WorkflowCoreRuntime);
                                removedActivityAction.OriginalRemovedActivity.Dispose();
                            }
                        }
                    }
                }
            }
        }
 protected void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
 {
     if (workflowChanges == null)
     {
         throw new ArgumentNullException("workflowChanges");
     }
     if (base.Parent != null)
     {
         throw new InvalidOperationException(SR.GetString("Error_InvalidActivityForWorkflowChanges"));
     }
     if (base.RootActivity == null)
     {
         throw new InvalidOperationException(SR.GetString("Error_MissingRootActivity"));
     }
     if (base.WorkflowCoreRuntime == null)
     {
         throw new InvalidOperationException(SR.GetString("Error_NoRuntimeAvailable"));
     }
     workflowChanges.ApplyTo(this);
 }
Esempio n. 9
0
 protected void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
 {
     if (workflowChanges == null)
     {
         throw new ArgumentNullException("workflowChanges");
     }
     if (base.Parent != null)
     {
         throw new InvalidOperationException(SR.GetString("Error_InvalidActivityForWorkflowChanges"));
     }
     if (base.RootActivity == null)
     {
         throw new InvalidOperationException(SR.GetString("Error_MissingRootActivity"));
     }
     if (base.WorkflowCoreRuntime == null)
     {
         throw new InvalidOperationException(SR.GetString("Error_NoRuntimeAvailable"));
     }
     workflowChanges.ApplyTo(this);
 }
Esempio n. 10
0
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="bIsManage"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool bIsManage)
        {
            if (bIsManage)
            {
                this.InnerWorkflowChanges = null;
                this.WorkflowEntity = null;

                this.InstanceId = Guid.Empty;
                this.TransientWorkflow = null;
            }
        }
Esempio n. 11
0
        protected internal override bool ApplyTo(Activity rootActivity)
        {
            if (rootActivity == null)
            {
                throw new ArgumentNullException("rootActivity");
            }
            if (!(rootActivity is CompositeActivity))
            {
                throw new ArgumentException(SR.GetString(SR.Error_RootActivityTypeInvalid), "rootActivity");
            }

            CompositeActivity ownerActivity = rootActivity.TraverseDottedPathFromRoot(this.OwnerActivityDottedPath) as CompositeActivity;

            if (ownerActivity == null)
            {
                return(false);
            }

            // !!!work around:
            ownerActivity.DynamicUpdateMode = true;
            CompositeActivity addedActivityOwner = this.addedActivity.Parent;

            try
            {
                this.addedActivity.SetParent(ownerActivity);
                Activity clonedAddedActivity = this.addedActivity;
                if (!this.addedActivity.DesignMode)
                {
                    clonedAddedActivity = this.addedActivity.Clone();
                }
                // We need to serialize and deserialize in order to clone during design mode
                else
                {
                    TypeProvider     typeProvider     = WorkflowChanges.CreateTypeProvider(rootActivity);
                    ServiceContainer serviceContainer = new ServiceContainer();
                    serviceContainer.AddService(typeof(ITypeProvider), typeProvider);
                    DesignerSerializationManager manager        = new DesignerSerializationManager(serviceContainer);
                    WorkflowMarkupSerializer     xomlSerializer = new WorkflowMarkupSerializer();
                    string addedActivityText = string.Empty;
                    // serialize dynamic updates
                    using (manager.CreateSession())
                    {
                        using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
                        {
                            using (XmlWriter xmlWriter = Helpers.CreateXmlWriter(sw))
                            {
                                WorkflowMarkupSerializationManager xomlSerializationManager = new WorkflowMarkupSerializationManager(manager);
                                xomlSerializer.Serialize(xomlSerializationManager, xmlWriter, this.addedActivity);
                                addedActivityText = sw.ToString();
                            }
                        }

                        // deserialize those
                        using (StringReader sr = new StringReader(addedActivityText))
                        {
                            using (XmlReader xmlReader = XmlReader.Create(sr))
                            {
                                WorkflowMarkupSerializationManager xomlSerializationManager = new WorkflowMarkupSerializationManager(manager);
                                clonedAddedActivity = xomlSerializer.Deserialize(xomlSerializationManager, xmlReader) as Activity;
                            }
                        }
                    }
                    if (clonedAddedActivity == null)
                    {
                        throw new InvalidOperationException(SR.GetString(SR.Error_ApplyDynamicChangeFailed));
                    }
                }
                if (ownerActivity.WorkflowCoreRuntime != null)
                {
                    ((IDependencyObjectAccessor)clonedAddedActivity).InitializeInstanceForRuntime(ownerActivity.WorkflowCoreRuntime);
                }

                clonedAddedActivity.SetParent(null);
                ownerActivity.Activities.Insert(this.index, clonedAddedActivity);
            }
            finally
            {
                this.addedActivity.SetParent(addedActivityOwner);
                ownerActivity.DynamicUpdateMode = false;
            }
            return(true);
        }
 public void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
 {
     using (new WorkflowTraceTransfer(this.InstanceId))
     {
         while (true)
         {
             WorkflowExecutor executor = _runtime.Load(this);
             if (executor.IsInstanceValid)
             {
                 try
                 {
                     executor.ApplyWorkflowChanges(workflowChanges);
                     break;
                 }
                 catch (InvalidOperationException)
                 {
                     if (executor.IsInstanceValid)
                         throw;
                 }
             }
         }
     }
 }
Esempio n. 13
0
        static void OnWorkflowIdled(object sender, WorkflowEventArgs e)
        {
            WorkflowInstance workflowInstance = e.WorkflowInstance;
            Activity wRoot = workflowInstance.GetWorkflowDefinition();

            //
            // use WorkflowChanges class to author dynamic change
            //
            WorkflowChanges changes = new WorkflowChanges(wRoot);
            Console.WriteLine("  Host is denying all PO requests - Removing POCreated step");
            //
            // remove POCreated activity
            //
            changes.TransientWorkflow.Activities.Remove(changes.TransientWorkflow.Activities["POCreated"]);
            //
            // apply transient changes to instance
            //
            workflowInstance.ApplyWorkflowChanges(changes);
        }
Esempio n. 14
0
        private void AddOrderOnHoldState()
        {
            // Get a reference to the WorkflowInstance for the selected workflow
            WorkflowInstance instance =
                this.runtime.GetWorkflow(this.GetSelectedWorkflowInstanceID());

            // Get a reference to the root activity for the workflow
            Activity root = instance.GetWorkflowDefinition();

            // Create a new instance of the WorkflowChanges class for managing
            // the in-memory changes to the workflow
            WorkflowChanges changes = new WorkflowChanges(root);

            // Create a new State activity to the workflow
            StateActivity orderOnHoldState = new StateActivity();
            orderOnHoldState.Name = "OrderOnHoldState";

            // Add a new EventDriven activity to the State
            EventDrivenActivity eventDrivenDelay = new EventDrivenActivity();
            eventDrivenDelay.Name = "DelayOrderEvent";
            orderOnHoldState.Activities.Add(eventDrivenDelay);

            // Add a new Delay, initialized to 5 seconds
            DelayActivity delayOrder = new DelayActivity();
            delayOrder.Name = "delayOrder";
            delayOrder.TimeoutDuration = new TimeSpan(0, 0, 5);
            eventDrivenDelay.Activities.Add(delayOrder);

            // Add a new SetState to the OrderOpenState
            SetStateActivity setStateOrderOpen = new SetStateActivity();
            setStateOrderOpen.TargetStateName = "OrderOpenState";
            eventDrivenDelay.Activities.Add(setStateOrderOpen);

            // Add the OnHoldState to the workflow
            changes.TransientWorkflow.Activities.Add(orderOnHoldState);
            
            // Apply the changes to the workflow instance
            try
            {
                instance.ApplyWorkflowChanges(changes);
            }
            catch (WorkflowValidationFailedException)
            {
                // New state has already been added
                MessageBox.Show("On Hold state has already been added to this workflow.");
            }
        }
Esempio n. 15
0
        static void OnWorkflowIdle(object sender, WorkflowEventArgs e)
        {
            if (wasChanged)
                return;

            wasChanged = true;

            WorkflowInstance workflowInstance = e.WorkflowInstance;

            Int32 newAmount = 15000;

            Console.WriteLine("Dynamically change approved amount to {0:c}",  newAmount);

            // Dynamic update of order rule
            WorkflowChanges workflowchanges = new WorkflowChanges(workflowInstance.GetWorkflowDefinition());
            
            CompositeActivity transient = workflowchanges.TransientWorkflow;
            RuleDefinitions ruleDefinitions = (RuleDefinitions)transient.GetValue(RuleDefinitions.RuleDefinitionsProperty);
            RuleConditionCollection conditions = ruleDefinitions.Conditions;
            RuleExpressionCondition condition1 = (RuleExpressionCondition)conditions["Check"];
            (condition1.Expression as CodeBinaryOperatorExpression).Right = new CodePrimitiveExpression(newAmount);

            workflowInstance.ApplyWorkflowChanges(workflowchanges);
        }
Esempio n. 16
0
        private void btnCreateSequentialWorkflow_Click(Object sender, EventArgs e)
        {
            ConnectionStringSettings persistenceConnectionString = cboPersistenceService.SelectedItem as ConnectionStringSettings;
            ConnectionStringSettings trackingConnectionString = cboTrackingService.SelectedItem as ConnectionStringSettings;
            if (persistenceConnectionString == null)
            {
                MessageBox.Show("No connection string selected for persistence service.", "WFTools Samples",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);

                return;
            }

            String workflowRuntimeKey = String.Format("{0}_{1}_{2}",
                persistenceConnectionString.Name, 
                trackingConnectionString == null ? "None" : trackingConnectionString.Name,
                chkUseLocalTransactions.Checked);

            SampleWorkFlowRuntime workflowRuntime;
            if (!this.loadedWorkflowRuntimes.TryGetValue(workflowRuntimeKey, out workflowRuntime))
            {
                workflowRuntime = new SampleWorkFlowRuntime(persistenceConnectionString,
                    trackingConnectionString, chkUseLocalTransactions.Checked);

                workflowRuntime.WorkflowTerminated += workflowRuntime_WorkflowTerminated;
                workflowRuntime.ServicesExceptionNotHandled += workflowRuntime_ServicesExceptionNotHandled;

                this.loadedWorkflowRuntimes.Add(workflowRuntimeKey, workflowRuntime);
            }

            // create a new sequential workflow
            WorkflowInstance workflowInstance = workflowRuntime.CreateSequentialWorkflow();

            if (chkModifyWorkflow.Checked)
            {
                Activity rootActivity = workflowInstance.GetWorkflowDefinition();
                WorkflowChanges workflowChanges = new WorkflowChanges(rootActivity);

                // modify the workflow
                Activity activityToRemove = workflowChanges.TransientWorkflow.GetActivityByName("codeActivity3");
                CompositeActivity parentActivity = activityToRemove.Parent;

                parentActivity.Activities.Remove(activityToRemove);

                CodeActivity codeActivity = new CodeActivity("TestChangeActivity");
                codeActivity.ExecuteCode +=
                    delegate { Trace.WriteLine("Test Change Activity executed..."); };

                parentActivity.Activities.Add(codeActivity);

                workflowInstance.ApplyWorkflowChanges(workflowChanges);
            }

            workflowInstance.Start();

            ManualWorkflowSchedulerService schedulerService = workflowRuntime.GetService<ManualWorkflowSchedulerService>();
            schedulerService.RunWorkflow(workflowInstance.InstanceId);
        }
        protected internal override bool ApplyTo(Activity rootActivity)
        {
            if (rootActivity == null)
            {
                throw new ArgumentNullException("rootActivity");
            }
            if (!(rootActivity is CompositeActivity))
            {
                throw new ArgumentException(SR.GetString("Error_RootActivityTypeInvalid"), "rootActivity");
            }
            CompositeActivity compositeActivity = rootActivity.TraverseDottedPathFromRoot(base.OwnerActivityDottedPath) as CompositeActivity;

            if (compositeActivity == null)
            {
                return(false);
            }
            compositeActivity.DynamicUpdateMode = true;
            CompositeActivity parent = this.addedActivity.Parent;

            try
            {
                this.addedActivity.SetParent(compositeActivity);
                Activity addedActivity = this.addedActivity;
                if (!this.addedActivity.DesignMode)
                {
                    addedActivity = this.addedActivity.Clone();
                }
                else
                {
                    TypeProvider     serviceInstance = WorkflowChanges.CreateTypeProvider(rootActivity);
                    ServiceContainer provider        = new ServiceContainer();
                    provider.AddService(typeof(ITypeProvider), serviceInstance);
                    DesignerSerializationManager manager    = new DesignerSerializationManager(provider);
                    WorkflowMarkupSerializer     serializer = new WorkflowMarkupSerializer();
                    string s = string.Empty;
                    using (manager.CreateSession())
                    {
                        using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
                        {
                            using (XmlWriter writer2 = Helpers.CreateXmlWriter(writer))
                            {
                                WorkflowMarkupSerializationManager serializationManager = new WorkflowMarkupSerializationManager(manager);
                                serializer.Serialize(serializationManager, writer2, this.addedActivity);
                                s = writer.ToString();
                            }
                        }
                        using (StringReader reader = new StringReader(s))
                        {
                            using (XmlReader reader2 = XmlReader.Create(reader))
                            {
                                WorkflowMarkupSerializationManager manager3 = new WorkflowMarkupSerializationManager(manager);
                                addedActivity = serializer.Deserialize(manager3, reader2) as Activity;
                            }
                        }
                    }
                    if (addedActivity == null)
                    {
                        throw new InvalidOperationException(SR.GetString("Error_ApplyDynamicChangeFailed"));
                    }
                }
                if (compositeActivity.WorkflowCoreRuntime != null)
                {
                    ((IDependencyObjectAccessor)addedActivity).InitializeInstanceForRuntime(compositeActivity.WorkflowCoreRuntime);
                }
                addedActivity.SetParent(null);
                compositeActivity.Activities.Insert(this.index, addedActivity);
            }
            finally
            {
                this.addedActivity.SetParent(parent);
                compositeActivity.DynamicUpdateMode = false;
            }
            return(true);
        }
Esempio n. 18
0
        /// <summary>
        /// Tries the load from ms workflow.
        /// </summary>
        /// <returns></returns>
        private bool TryLoadFromMsWorkflow()
        {
            try
            {
                WorkflowInstance instance = GlobalWorkflowRuntime.WorkflowRuntime.GetWorkflow(this.InstanceId);
                Activity root = instance.GetWorkflowDefinition();

                if(this.WorkflowEntity == null)
                    this.WorkflowEntity = BusinessManager.Load(WorkflowInstanceEntity.ClassName, new PrimaryKeyId(this.InstanceId));

                this.InnerWorkflowChanges = new WorkflowChanges(root);
                this.TransientWorkflow = this.InnerWorkflowChanges.TransientWorkflow;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.ToString(), "Mediachase.Ibn.Assignments::TryLoadFromMsWorkflow");
                return false;
            }

            return true;
        }
Esempio n. 19
0
        public void Load(String path)
        {
            _tx = new System.Workflow.ComponentModel.WorkflowChanges(this);
            _tx.TransientWorkflow.Activities.Clear();

            this.AddButton("b1");
            this.AddButton("b2");

            this._serviceInterface = this.CreateServiceInterface();
            this._serviceImplementation = this.CreateServiceImplementation(this._serviceInterface);
            PressState ps1 = new ImageState("ps1", "img.png", this._serviceInterface);
            PressState ps2 = new AnimationState("ps2", "", 123, this._serviceInterface);

            this.AddState(ps1);
            this.AddState(ps2);
            ps1.AddTrigger("b1", "ps2");
            ps2.AddTrigger("b2", "ps1");
            this.SetInitial(ps1);
        }
Esempio n. 20
0
        internal void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
        {
            // Accessing InstanceId is not thread safe here!
            //WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Got a dynamic update request from outside for instance {0}", this.InstanceIdString);
            DiagnosticStackTrace("dynamic update request");

            // check arguments
            if (workflowChanges == null)
                throw new ArgumentNullException("workflowChanges");

            // check if this is a valid in-memory instance
            if (!this.IsInstanceValid)
                throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid);

            if (this.currentAtomicActivity != null)
                throw new InvalidOperationException(ExecutionStringManager.Error_InsideAtomicScope);

            try
            {
                using (ScheduleWork work = new ScheduleWork(this))
                {
                    // block other instance operations from outside
                    using (this._executorLock.Enter())
                    {
                        // check if this is a valid in-memory instance
                        if (!this.IsInstanceValid)
                            throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid);

                        // get the instance to stop running
                        this.Scheduler.CanRun = false;
                        using (new SchedulerLockGuard(this._schedulerLock, this))
                        {
                            using (new ServiceEnvironment(this.rootActivity))
                            {
                                bool localSuspend = false;

                                // check if this is a valid in-memory instance
                                if (!this.IsInstanceValid)
                                    throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid);

                                try
                                {
                                    // check the status of the schedule
                                    switch (this.WorkflowStatus)
                                    {
                                        ////case ActivityExecutionStatus.Completed:
                                        // 
                                        case WorkflowStatus.Completed:
                                        case WorkflowStatus.Terminated:
                                            throw new InvalidOperationException(
                                                ExecutionStringManager.InvalidOperationRequest);
                                        case WorkflowStatus.Suspended:
                                            // instance already suspended
                                            localSuspend = false;
                                            break;
                                        default:
                                            // suspend the instance
                                            this.SuspendOnIdle(null);
                                            localSuspend = true;
                                            break;
                                    }

                                    // apply the changes
                                    workflowChanges.ApplyTo(this.rootActivity);
                                }
                                finally
                                {
                                    if (localSuspend)
                                    {
                                        // @undone: for now this will not return till the instance is done
                                        // Once Kumar has fixed 4335, we can enable this.
                                        this.ResumeOnIdle(true);
                                    }
                                }
                            }
                        } // release lock on scheduler
                    }
                }
            }
            catch (Exception e)
            {
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: dynamic update attempt from outside on instance '{0}' threw an exception '{1}' at {2}", this.InstanceIdString, e.Message, e.StackTrace);
                throw;
            }
        }
        internal void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
        {
            if (workflowChanges == null)
            {
                throw new ArgumentNullException("workflowChanges");
            }
            if (!this.IsInstanceValid)
            {
                throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid);
            }
            if (this.currentAtomicActivity != null)
            {
                throw new InvalidOperationException(ExecutionStringManager.Error_InsideAtomicScope);
            }
            try
            {
                using (new ScheduleWork(this))
                {
                    using (this._executorLock.Enter())
                    {
                        if (!this.IsInstanceValid)
                        {
                            throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid);
                        }
                        this.Scheduler.CanRun = false;
                        using (new SchedulerLockGuard(this._schedulerLock, this))
                        {
                            using (new ServiceEnvironment(this.rootActivity))
                            {
                                bool flag = false;
                                if (!this.IsInstanceValid)
                                {
                                    throw new InvalidOperationException(ExecutionStringManager.WorkflowNotValid);
                                }
                                try
                                {
                                    switch (this.WorkflowStatus)
                                    {
                                        case System.Workflow.Runtime.WorkflowStatus.Completed:
                                        case System.Workflow.Runtime.WorkflowStatus.Terminated:
                                            throw new InvalidOperationException(ExecutionStringManager.InvalidOperationRequest);

                                        case System.Workflow.Runtime.WorkflowStatus.Suspended:
                                            flag = false;
                                            break;

                                        default:
                                            this.SuspendOnIdle(null);
                                            flag = true;
                                            break;
                                    }
                                    workflowChanges.ApplyTo(this.rootActivity);
                                }
                                finally
                                {
                                    if (flag)
                                    {
                                        this.ResumeOnIdle(true);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: dynamic update attempt from outside on instance '{0}' threw an exception '{1}' at {2}", new object[] { this.InstanceIdString, exception.Message, exception.StackTrace });
                throw;
            }
        }