public override bool Equals(object obj) { ReplicatorSubscriber subscriber = obj as ReplicatorSubscriber; return(subscriber != null && base.Equals(obj) && (this.runId.Equals(subscriber.runId))); }
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")); } } }
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)); } }