private void RemoveAt(int index) { if (base.ExecutionStatus != ActivityExecutionStatus.Executing) { throw new InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting")); } if (this.ActivityState == null) { throw new InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized")); } if ((index < 0) || (index >= this.ActivityState.AbsoluteCount)) { throw new ArgumentOutOfRangeException("index"); } ChildExecutionStateInfo item = this.ActivityState[index, false]; if ((item.Status == ChildRunStatus.Completed) || (item.Status == ChildRunStatus.Created)) { this.ActivityState.Remove(item); } else { item.MarkedForRemoval = true; base.Invoke <ReplicatorInterActivityEventArgs>(new EventHandler <ReplicatorInterActivityEventArgs>(this.HandleChildUpdateOperation), new ReplicatorInterActivityEventArgs(item, false)); } }
private int IndexOf(object value) { if (base.ExecutionStatus != ActivityExecutionStatus.Executing) { throw new InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting")); } if (this.ActivityState == null) { throw new InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized")); } int num = 0; for (int i = 0; i < this.ActivityState.Count; i++) { ChildExecutionStateInfo info = this.ActivityState[i]; if (!info.MarkedForRemoval) { if (object.Equals(info.InstanceData, value)) { return(num); } num++; } } return(-1); }
private bool TryCancelChild(ActivityExecutionContext outerProvider, ChildExecutionStateInfo childStateInfo) { bool flag = false; ActivityExecutionContextManager executionContextManager = outerProvider.ExecutionContextManager; ActivityExecutionContext executionContext = this.GetExecutionContext(executionContextManager, childStateInfo.RunId); if (executionContext != null) { switch (executionContext.Activity.ExecutionStatus) { case ActivityExecutionStatus.Executing: executionContext.CancelActivity(executionContext.Activity); return(true); case ActivityExecutionStatus.Canceling: case ActivityExecutionStatus.Faulting: return(true); case ActivityExecutionStatus.Closed: case ActivityExecutionStatus.Compensating: return(flag); } return(flag); } if ((base.ExecutionStatus != ActivityExecutionStatus.Executing) && (childStateInfo.Status == ChildRunStatus.PendingExecute)) { childStateInfo.Status = ChildRunStatus.Completed; } return(flag); }
private void RemoveAt(int index) { if (this.ExecutionStatus != ActivityExecutionStatus.Executing) { throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting)); } if (this.ActivityState == null) { throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized)); } if (index < 0 || index >= this.ActivityState.AbsoluteCount) { throw new ArgumentOutOfRangeException("index"); } ChildExecutionStateInfo childStateInfo = this.ActivityState[index, false]; if (childStateInfo.Status == ChildRunStatus.Completed || childStateInfo.Status == ChildRunStatus.Created) { this.ActivityState.Remove(childStateInfo); } else { childStateInfo.MarkedForRemoval = true; base.Invoke(this.HandleChildUpdateOperation, new ReplicatorInterActivityEventArgs(childStateInfo, false)); } }
private void Insert(int index, object value) { if (value == null) { throw new ArgumentNullException("value"); } if (this.ExecutionStatus != ActivityExecutionStatus.Executing) { throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting)); } if (this.ActivityState == null) { throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized)); } if (index < 0 || index > this.ActivityState.AbsoluteCount) { throw new ArgumentOutOfRangeException("index"); } ChildExecutionStateInfo childStateInfo = new ChildExecutionStateInfo(value); this.ActivityState.Insert(index, childStateInfo, false); ScheduleExecutionIfNeeded(childStateInfo, index); }
private int IndexOf(object value) { if (this.ExecutionStatus != ActivityExecutionStatus.Executing) { throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting)); } if (this.ActivityState == null) { throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized)); } int absoluteIndex = 0; for (int i = 0; i < this.ActivityState.Count; ++i) { ChildExecutionStateInfo childStateInfo = this.ActivityState[i]; if (!childStateInfo.MarkedForRemoval) { if (Object.Equals(childStateInfo.InstanceData, value)) { return(absoluteIndex); } else { ++absoluteIndex; } } } return(-1); }
private void CancelChildExecution(ActivityExecutionContext executionContext, ChildExecutionStateInfo childStateInfo) { if (childStateInfo.Status != ChildRunStatus.Running) { this.ActivityState.Remove(childStateInfo); } else { this.TryCancelChild(executionContext, childStateInfo); } }
public bool IsExecuting(int index) { if (this.ActivityState != null) { if (index < 0 || index >= this.ActivityState.AbsoluteCount) { throw new ArgumentOutOfRangeException("index"); } ChildExecutionStateInfo childStateInfo = this.ActivityState[index, false]; return(childStateInfo.Status == ChildRunStatus.PendingExecute || childStateInfo.Status == ChildRunStatus.Running); } return(false); }
private void CancelChildExecution(ActivityExecutionContext executionContext, ChildExecutionStateInfo childStateInfo) { // Mark the Instance For Removal System.Diagnostics.Debug.Assert(childStateInfo.MarkedForRemoval); // check if the instance is currently executing if (childStateInfo.Status != ChildRunStatus.Running) //It is passive, then we can safely remove the State. { this.ActivityState.Remove(childStateInfo); return; } // schedule the child cancellation // once this run is cancelled, the handleEvent should remove this from execution state. TryCancelChild(executionContext, childStateInfo); }
private int Add(object value) { if (base.ExecutionStatus != ActivityExecutionStatus.Executing) { throw new InvalidOperationException(SR.GetString("Error_ReplicatorNotExecuting")); } if (this.ActivityState == null) { throw new InvalidOperationException(SR.GetString("Error_ReplicatorNotInitialized")); } ChildExecutionStateInfo item = new ChildExecutionStateInfo(value); this.ActivityState.Add(item); int index = this.ActivityState.AbsoluteCount - 1; this.ScheduleExecutionIfNeeded(item, index); return(index); }
private void ScheduleExecutionIfNeeded(ChildExecutionStateInfo childStateInfo, int index) { bool flag = this.ExecutionType == System.Workflow.Activities.ExecutionType.Parallel; if (!flag) { int absoluteCount = this.ActivityState.AbsoluteCount; if (((index == 0) && (absoluteCount == 1)) || ((index == (absoluteCount - 1)) && (this.ActivityState[absoluteCount - 2, false].Status == ChildRunStatus.Completed))) { flag = true; } } if (flag) { childStateInfo.Status = ChildRunStatus.PendingExecute; base.Invoke <ReplicatorInterActivityEventArgs>(new EventHandler <ReplicatorInterActivityEventArgs>(this.HandleChildUpdateOperation), new ReplicatorInterActivityEventArgs(childStateInfo, true)); } }
public bool IsExecuting(int index) { if (this.ActivityState == null) { return(false); } if ((index < 0) || (index >= this.ActivityState.AbsoluteCount)) { throw new ArgumentOutOfRangeException("index"); } ChildExecutionStateInfo info = this.ActivityState[index, false]; if (info.Status != ChildRunStatus.PendingExecute) { return(info.Status == ChildRunStatus.Running); } return(true); }
bool TryCancelChild(ActivityExecutionContext outerProvider, ChildExecutionStateInfo childStateInfo) { // schedule cancellation of the child in the inner execution context bool fScheduledCancel = false; // returns true iff scheduled cancel on one execution of the template // false if execution already closed // get the execution context for this run ActivityExecutionContextManager contextManager = outerProvider.ExecutionContextManager; ActivityExecutionContext innerProvider = GetExecutionContext(contextManager, childStateInfo.RunId); if (innerProvider != null) { switch (innerProvider.Activity.ExecutionStatus) { case ActivityExecutionStatus.Executing: // schedule cancellation on child innerProvider.CancelActivity(innerProvider.Activity); fScheduledCancel = true; break; case ActivityExecutionStatus.Canceling: case ActivityExecutionStatus.Faulting: fScheduledCancel = true; break; default: // do nothing break; } } else { //Finish the run if it is pending for execution. if (this.ExecutionStatus != ActivityExecutionStatus.Executing && childStateInfo.Status == ChildRunStatus.PendingExecute) { childStateInfo.Status = ChildRunStatus.Completed; } } return(fScheduledCancel); }
//Schedules execution if mode is parallel or if the insert is at head of empty list //or tail of all completed list in sequence case. void ScheduleExecutionIfNeeded(ChildExecutionStateInfo childStateInfo, int index) { bool bShouldExecute = (this.ExecutionType == ExecutionType.Parallel); if (!bShouldExecute) //Sequence Case. { //Execute if its head and only node or tail and previous tail already completed. int totalListSize = this.ActivityState.AbsoluteCount; if ((index == 0 && totalListSize == 1) || ((index == totalListSize - 1) && this.ActivityState[totalListSize - 2, false].Status == ChildRunStatus.Completed)) { bShouldExecute = true; } } if (bShouldExecute) { childStateInfo.Status = ChildRunStatus.PendingExecute; base.Invoke(this.HandleChildUpdateOperation, new ReplicatorInterActivityEventArgs(childStateInfo, true)); } }
private void ExecuteTemplate(ActivityExecutionContext executionContext, ChildExecutionStateInfo childStateInfo) { ActivityExecutionContextManager executionContextManager = executionContext.ExecutionContextManager; ActivityExecutionContext childContext = executionContextManager.CreateExecutionContext(base.EnabledActivities[0]); childStateInfo.RunId = childContext.ContextGuid; childStateInfo.Status = ChildRunStatus.Running; try { base.RaiseGenericEvent <ReplicatorChildEventArgs>(ChildInitializedEvent, this, new ReplicatorChildEventArgs(childStateInfo.InstanceData, childContext.Activity)); } catch { childStateInfo.RunId = Guid.Empty; childStateInfo.Status = ChildRunStatus.Completed; executionContextManager.CompleteExecutionContext(childContext); throw; } childContext.ExecuteActivity(childContext.Activity); childContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, new ReplicatorSubscriber(this, childContext.ContextGuid)); }
private int Add(object value) { if (this.ExecutionStatus != ActivityExecutionStatus.Executing) { throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting)); } if (this.ActivityState == null) { throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized)); } ChildExecutionStateInfo childStateInfo = new ChildExecutionStateInfo(value); this.ActivityState.Add(childStateInfo); int indexOfAdd = this.ActivityState.AbsoluteCount - 1; ScheduleExecutionIfNeeded(childStateInfo, indexOfAdd); return(indexOfAdd); }
private void ExecuteTemplate(ActivityExecutionContext executionContext, ChildExecutionStateInfo childStateInfo) { System.Diagnostics.Debug.Assert(childStateInfo.Status != ChildRunStatus.Running); ActivityExecutionContextManager contextManager = executionContext.ExecutionContextManager; ActivityExecutionContext templateExecutionContext = contextManager.CreateExecutionContext(this.EnabledActivities[0]); childStateInfo.RunId = templateExecutionContext.ContextGuid; childStateInfo.Status = ChildRunStatus.Running; try { base.RaiseGenericEvent(ReplicatorActivity.ChildInitializedEvent, this, new ReplicatorChildEventArgs(childStateInfo.InstanceData, templateExecutionContext.Activity)); } catch { childStateInfo.RunId = Guid.Empty; childStateInfo.Status = ChildRunStatus.Completed; contextManager.CompleteExecutionContext(templateExecutionContext); throw; } templateExecutionContext.ExecuteActivity(templateExecutionContext.Activity); templateExecutionContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, new ReplicatorSubscriber(this, templateExecutionContext.ContextGuid)); }
internal ReplicatorInterActivityEventArgs(ChildExecutionStateInfo childStateInfo, bool isAdd) { this.childStateInfo = childStateInfo; this.isAdd = isAdd; }
private void HandleStatusChange(ActivityExecutionContext executionContext, ActivityExecutionStatusChangedEventArgs e, ReplicatorSubscriber subscriber) { //System.Diagnostics.Debug.Assert(this.ExecutionStatus != ActivityExecutionStatus.Closed, "Stale notification should not have reache here"); //System.Diagnostics.Debug.Assert(e.Activity.QualifiedName.Equals(this.EnabledActivities[0].QualifiedName), "Got status change notification of non existing child"); //System.Diagnostics.Debug.Assert(subscriber.RunIdentifier != Guid.Empty, "Got notification from non-running template instance"); //Perform cleanup on completed run. int runIndex = this.ActivityState.FindIndexOfChildStateInfo(subscriber.RunIdentifier); if (runIndex == -1) { //This will happen when CancelChild is issued after Child Closed //but before StatusChange Event raised on parent. return; } ChildExecutionStateInfo childStateInfo = this.ActivityState[runIndex]; bool isMarkedForRemoval = childStateInfo.MarkedForRemoval; try { try { base.RaiseGenericEvent(ReplicatorActivity.ChildCompletedEvent, this, new ReplicatorChildEventArgs(childStateInfo.InstanceData, e.Activity)); e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, subscriber); } finally { ActivityExecutionContextManager contextManager = executionContext.ExecutionContextManager; ActivityExecutionContext templateExecutionContext = contextManager.GetExecutionContext(e.Activity); contextManager.CompleteExecutionContext(templateExecutionContext); } //Reevaluate CompletionCondition if (!this.ActivityState.CompletionConditionTrueAlready) { this.ActivityState.CompletionConditionTrueAlready = (this.UntilCondition != null && this.UntilCondition.Evaluate(this, executionContext)); } } finally //Always perform cleanup of just completed child. { //This will mark child as passive. childStateInfo.RunId = Guid.Empty; childStateInfo.Status = ChildRunStatus.Completed; if (isMarkedForRemoval) { //This is the case, when user issued CancelChild request on running template instance. //We flush out execution state of that run when it becomes passive. this.ActivityState.Remove(childStateInfo); runIndex = runIndex - 1; //Needed for sequence execution type. } } //Next Step. if (!this.ActivityState.IsChildActive) //Everything is passive now. { if (this.ExecutionStatus == ActivityExecutionStatus.Canceling || this.ExecutionStatus == ActivityExecutionStatus.Faulting || this.ActivityState.CompletionConditionTrueAlready) { base.RaiseEvent(ReplicatorActivity.CompletedEvent, this, EventArgs.Empty); executionContext.CloseActivity(); return; } } else //Template is active; Valid only for parallel { System.Diagnostics.Debug.Assert(this.ExecutionType == ExecutionType.Parallel); if (this.ExecutionStatus != ActivityExecutionStatus.Canceling && this.ExecutionStatus != ActivityExecutionStatus.Faulting) { if (this.ActivityState.CompletionConditionTrueAlready) { //Try cool down child. TryCancelChildren(executionContext); return; } } } switch (this.ExecutionType) { case ExecutionType.Sequence: if (runIndex < this.ActivityState.Count - 1) { ExecuteTemplate(executionContext, this.ActivityState[runIndex + 1]); return; } else if (this.UntilCondition == null || this.UntilCondition.Evaluate(this, executionContext)) { base.RaiseEvent(ReplicatorActivity.CompletedEvent, this, EventArgs.Empty); executionContext.CloseActivity(); return; } break; case ExecutionType.Parallel: if (!this.ActivityState.IsChildActive && (this.UntilCondition == null || (this.UntilCondition.Evaluate(this, executionContext)))) { base.RaiseEvent(ReplicatorActivity.CompletedEvent, this, EventArgs.Empty); executionContext.CloseActivity(); return; } break; default: throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorInvalidExecutionType)); } }
private void HandleStatusChange(ActivityExecutionContext executionContext, ActivityExecutionStatusChangedEventArgs e, ReplicatorSubscriber subscriber) { int num = this.ActivityState.FindIndexOfChildStateInfo(subscriber.RunIdentifier); if (num != -1) { ChildExecutionStateInfo item = this.ActivityState[num]; bool markedForRemoval = item.MarkedForRemoval; try { try { base.RaiseGenericEvent <ReplicatorChildEventArgs>(ChildCompletedEvent, this, new ReplicatorChildEventArgs(item.InstanceData, e.Activity)); e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, subscriber); } finally { ActivityExecutionContextManager executionContextManager = executionContext.ExecutionContextManager; ActivityExecutionContext childContext = executionContextManager.GetExecutionContext(e.Activity); executionContextManager.CompleteExecutionContext(childContext); } if (!this.ActivityState.CompletionConditionTrueAlready) { this.ActivityState.CompletionConditionTrueAlready = (this.UntilCondition != null) && this.UntilCondition.Evaluate(this, executionContext); } } finally { item.RunId = Guid.Empty; item.Status = ChildRunStatus.Completed; if (markedForRemoval) { this.ActivityState.Remove(item); num--; } } if (!this.ActivityState.IsChildActive) { if (((base.ExecutionStatus == ActivityExecutionStatus.Canceling) || (base.ExecutionStatus == ActivityExecutionStatus.Faulting)) || this.ActivityState.CompletionConditionTrueAlready) { base.RaiseEvent(CompletedEvent, this, EventArgs.Empty); executionContext.CloseActivity(); return; } } else if (((base.ExecutionStatus != ActivityExecutionStatus.Canceling) && (base.ExecutionStatus != ActivityExecutionStatus.Faulting)) && this.ActivityState.CompletionConditionTrueAlready) { this.TryCancelChildren(executionContext); return; } switch (this.ExecutionType) { case System.Workflow.Activities.ExecutionType.Sequence: if (num >= (this.ActivityState.Count - 1)) { if ((this.UntilCondition == null) || this.UntilCondition.Evaluate(this, executionContext)) { base.RaiseEvent(CompletedEvent, this, EventArgs.Empty); executionContext.CloseActivity(); return; } break; } this.ExecuteTemplate(executionContext, this.ActivityState[num + 1]); return; case System.Workflow.Activities.ExecutionType.Parallel: if (this.ActivityState.IsChildActive || ((this.UntilCondition != null) && !this.UntilCondition.Evaluate(this, executionContext))) { break; } base.RaiseEvent(CompletedEvent, this, EventArgs.Empty); executionContext.CloseActivity(); return; default: throw new InvalidOperationException(SR.GetString("Error_ReplicatorInvalidExecutionType")); } } }