Example #1
0
        private ActivityExecutionStatus CompensateTargetActivity(ActivityExecutionContext context)
        {
            Activity activityByName = null;
            Activity activity2      = context.Activity;

            do
            {
                activityByName = activity2.Parent.GetActivityByName(this.TargetActivityName, true);
            }while (activityByName == null);
            if (((activityByName is ICompensatableActivity) && (activityByName.ExecutionStatus == ActivityExecutionStatus.Closed)) && (activityByName.ExecutionResult == ActivityExecutionResult.Succeeded))
            {
                activityByName.RegisterForStatusChange(Activity.ClosedEvent, this);
                context.CompensateActivity(activityByName);
                return(context.Activity.ExecutionStatus);
            }
            if (activityByName.ExecutionStatus == ActivityExecutionStatus.Initialized)
            {
                ActivityExecutionContextManager executionContextManager = context.ExecutionContextManager;
                foreach (ActivityExecutionContext context2 in executionContextManager.ExecutionContexts)
                {
                    if ((activityByName.GetActivityByName(context2.Activity.QualifiedName, true) != null) && (((context2.Activity.ExecutionStatus == ActivityExecutionStatus.Compensating) || (context2.Activity.ExecutionStatus == ActivityExecutionStatus.Faulting)) || (context2.Activity.ExecutionStatus == ActivityExecutionStatus.Canceling)))
                    {
                        return(context.Activity.ExecutionStatus);
                    }
                }
                for (int i = executionContextManager.CompletedExecutionContexts.Count - 1; i >= 0; i--)
                {
                    ActivityExecutionContextInfo contextInfo = executionContextManager.CompletedExecutionContexts[i];
                    if (((byte)(contextInfo.Flags & PersistFlags.NeedsCompensation)) != 0)
                    {
                        ActivityExecutionContext context3 = executionContextManager.DiscardPersistedExecutionContext(contextInfo);
                        if (context3.Activity is ICompensatableActivity)
                        {
                            context3.Activity.RegisterForStatusChange(Activity.ClosedEvent, this);
                            context3.CompensateActivity(context3.Activity);
                        }
                        return(context.Activity.ExecutionStatus);
                    }
                }
            }
            else if (CompensationUtils.TryCompensateLastCompletedChildActivity(context, activityByName, this))
            {
                return(context.Activity.ExecutionStatus);
            }
            return(ActivityExecutionStatus.Closed);
        }
        void IActivityEventListener <ActivityExecutionStatusChangedEventArgs> .OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext context = sender as ActivityExecutionContext;

            if (context == null)
            {
                throw new ArgumentException("sender");
            }
            if (e.Activity == context.Activity)
            {
                if (context.Activity.HasPrimaryClosed && !((bool)context.Activity.GetValue(CompensateProcessedProperty)))
                {
                    context.Activity.SetValue(CompensateProcessedProperty, true);
                    if (context.Activity.ExecutionResult != ActivityExecutionResult.Compensated)
                    {
                        context.Activity.ReleaseLockOnStatusChange(this);
                    }
                    else
                    {
                        Activity compensationHandler = GetCompensationHandler(context.Activity);
                        if (compensationHandler != null)
                        {
                            compensationHandler.RegisterForStatusChange(Activity.ClosedEvent, this);
                            context.ExecuteActivity(compensationHandler);
                        }
                        else if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                        {
                            context.Activity.ReleaseLockOnStatusChange(this);
                        }
                    }
                }
            }
            else if ((e.Activity is CompensationHandlerActivity) && (e.ExecutionStatus == ActivityExecutionStatus.Closed))
            {
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                context.Activity.ReleaseLockOnStatusChange(this);
            }
            else if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    context.Activity.ReleaseLockOnStatusChange(this);
                }
            }
        }
Example #3
0
 public override ActivityExecutionStatus Execute(Activity activity, ActivityExecutionContext executionContext)
 {
     if (executionContext == null)
     {
         throw new ArgumentNullException("executionContext");
     }
     if (activity == null)
     {
         throw new ArgumentNullException("activity");
     }
     if (!activity.SupportsTransaction)
     {
         throw new ArgumentException("activity");
     }
     activity.RegisterForStatusChange(Activity.LockCountOnStatusChangeChangedEvent, this);
     activity.HoldLockOnStatusChange(this);
     return(ExecuteActivity(activity, executionContext, false));
 }
 public override ActivityExecutionStatus Execute(Activity activity, ActivityExecutionContext executionContext)
 {
     if (executionContext == null)
     {
         throw new ArgumentNullException("executionContext");
     }
     if (activity == null)
     {
         throw new ArgumentNullException("activity");
     }
     activity.RegisterForStatusChange(Activity.LockCountOnStatusChangeChangedEvent, this);
     activity.HoldLockOnStatusChange(this);
     if (executionContext.AcquireLocks(this))
     {
         return(this.ExecuteActivityNow(executionContext));
     }
     return(activity.ExecutionStatus);
 }
Example #5
0
        private static bool TryCompensateLastCompletedChildActivity(ActivityExecutionContext context, Activity targetActivity, IActivityEventListener <ActivityExecutionStatusChangedEventArgs> statusChangeHandler, bool isimmediateCompensation)
        {
            SortedDictionary <int, CompensationInfo> sortedListOfCompensatableTargets = new SortedDictionary <int, CompensationInfo>();

            if (targetActivity is CompositeActivity)
            {
                if (CollectCompensatableTargetActivities(targetActivity as CompositeActivity, sortedListOfCompensatableTargets, isimmediateCompensation))
                {
                    return(true);
                }
                if (CollectCompensatableActiveContexts(context, targetActivity, sortedListOfCompensatableTargets, isimmediateCompensation))
                {
                    return(true);
                }
                CollectCompensatableCompletedContexts(context, targetActivity, sortedListOfCompensatableTargets, isimmediateCompensation);
                if (sortedListOfCompensatableTargets.Count == 0)
                {
                    CompleteRevokedExecutionContext(targetActivity, context);
                    return(false);
                }
                int?nullable          = targetActivity.GetValue(CompensationHandlingFilter.LastCompensatedOrderIdProperty) as int?;
                int num               = -1;
                CompensationInfo info = null;
                foreach (int num2 in sortedListOfCompensatableTargets.Keys)
                {
                    if (nullable.HasValue)
                    {
                        int?nullable2 = nullable;
                        int num3      = num2;
                        if ((nullable2.GetValueOrDefault() < num3) && nullable2.HasValue)
                        {
                            break;
                        }
                    }
                    info = sortedListOfCompensatableTargets[num2];
                    num  = num2;
                }
                if (info == null)
                {
                    CompleteRevokedExecutionContext(targetActivity, context);
                    return(false);
                }
                targetActivity.SetValue(CompensationHandlingFilter.LastCompensatedOrderIdProperty, num);
                if ((info.TargetActivity != null) && (info.TargetActivity is ICompensatableActivity))
                {
                    info.TargetActivity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler);
                    context.CompensateActivity(info.TargetActivity);
                    return(true);
                }
                if ((info.TargetExecutionInfo != null) && (info.TargetExecutionContextManager != null))
                {
                    ActivityExecutionContext context2 = info.TargetExecutionContextManager.DiscardPersistedExecutionContext(info.TargetExecutionInfo);
                    if (context2.Activity is ICompensatableActivity)
                    {
                        context2.Activity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler);
                        context2.CompensateActivity(context2.Activity);
                        return(true);
                    }
                    if (context2.Activity is CompositeActivity)
                    {
                        Activity lastCompensatableChild = GetLastCompensatableChild(context2.Activity as CompositeActivity);
                        if (lastCompensatableChild != null)
                        {
                            lastCompensatableChild.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler);
                            context2.CompensateActivity(lastCompensatableChild);
                            return(true);
                        }
                        return(TryCompensateLastCompletedChildActivity(context2, context2.Activity, statusChangeHandler, false));
                    }
                }
                else if ((info.TargetExecutionContext != null) && (info.TargetExecutionContext.Activity is CompositeActivity))
                {
                    Activity activity = GetLastCompensatableChild(info.TargetExecutionContext.Activity as CompositeActivity);
                    if (activity != null)
                    {
                        activity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler);
                        info.TargetExecutionContext.CompensateActivity(activity);
                        return(true);
                    }
                    return(TryCompensateLastCompletedChildActivity(info.TargetExecutionContext, info.TargetExecutionContext.Activity, statusChangeHandler, false));
                }
            }
            return(false);
        }
        void IActivityEventListener <ActivityExecutionStatusChangedEventArgs> .OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext context = sender as ActivityExecutionContext;

            if (context == null)
            {
                throw new ArgumentException("sender");
            }

            if (e.Activity == context.Activity)
            {
                if (context.Activity.HasPrimaryClosed && !(bool)context.Activity.GetValue(CompensateProcessedProperty))
                {
                    context.Activity.SetValue(CompensateProcessedProperty, true);
                    if (context.Activity.ExecutionResult == ActivityExecutionResult.Compensated)
                    {
                        // run compensation handler or do default compensation handling
                        Activity compensationHandler = GetCompensationHandler(context.Activity);
                        if (compensationHandler != null)
                        {
                            // subscribe for status change on compensation handler
                            compensationHandler.RegisterForStatusChange(Activity.ClosedEvent, this);

                            // execute compensation handler
                            context.ExecuteActivity(compensationHandler);
                        }
                        else
                        {
                            // do default compensation
                            if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                            {
                                // let activity get into closed state
                                context.Activity.ReleaseLockOnStatusChange(this);
                            }
                        }
                    }
                    else
                    {
                        // let activity get into closed state
                        context.Activity.ReleaseLockOnStatusChange(this);
                    }
                }
            }
            else if (e.Activity is CompensationHandlerActivity && e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                // remove subscriber for status change on compensation handler
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);

                // release lock on the primary activity
                context.Activity.ReleaseLockOnStatusChange(this);
            }
            else if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                // remove subscriber for status change on compensated activity
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);

                if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    // release lock on the primary activity
                    context.Activity.ReleaseLockOnStatusChange(this);
                }
            }
        }
        private static bool TryCompensateLastCompletedChildActivity(ActivityExecutionContext context, Activity targetActivity, IActivityEventListener <ActivityExecutionStatusChangedEventArgs> statusChangeHandler, bool isimmediateCompensation)
        {
            SortedDictionary <int, CompensationInfo> sortedListOfCompensatableTargets = new SortedDictionary <int, CompensationInfo>();

            if (!(targetActivity is CompositeActivity))
            {
                return(false);
            }

            //Walk through all of the direct children which are compensatable and add them in the sorted order of their completion
            //bail out if any of the compensatable children is currently compensating/faulting or canceling
            if (CollectCompensatableTargetActivities(targetActivity as CompositeActivity, sortedListOfCompensatableTargets, isimmediateCompensation))
            {
                return(true);
            }

            // walk through active contexts that contain compensatable child, add them in the sorted order of the completion
            // this also, walks through the completed contexts which are compensatable and are nested directly within the active contexts and adds them in the order of their completion
            // bail out if any activity is currently compensating/faulting or cancelling
            if (CollectCompensatableActiveContexts(context, targetActivity, sortedListOfCompensatableTargets, isimmediateCompensation))
            {
                return(true);
            }

            // walk through all completed execution contexts which are compensatable and are directly nested under the target activity,
            //and add them to our sorted list
            CollectCompensatableCompletedContexts(context, targetActivity, sortedListOfCompensatableTargets, isimmediateCompensation);

            //if there were no compensatable targets found, bail out
            if (sortedListOfCompensatableTargets.Count == 0)
            {
                CompleteRevokedExecutionContext(targetActivity, context);
                return(false);
            }

            int?lastCompletedOrderId     = targetActivity.GetValue(CompensationHandlingFilter.LastCompensatedOrderIdProperty) as Nullable <int>;
            int nextLastCompletedOrderId = -1;
            //get the last compensatable target - this could be an activity, contextInfo or a Context
            CompensationInfo lastCompensatableTarget = null;

            foreach (int completedOrderId in sortedListOfCompensatableTargets.Keys)
            {
                if (lastCompletedOrderId.HasValue && lastCompletedOrderId < completedOrderId)
                {
                    break;
                }

                lastCompensatableTarget  = sortedListOfCompensatableTargets[completedOrderId];
                nextLastCompletedOrderId = completedOrderId;
            }

            //We are done with compensation on entire branch, now complete execution contexts
            //recursilvely which we might have opened up.
            if (lastCompensatableTarget == null)
            {
                CompleteRevokedExecutionContext(targetActivity, context);
                return(false);
            }

            targetActivity.SetValue(CompensationHandlingFilter.LastCompensatedOrderIdProperty, nextLastCompletedOrderId);

            //the last compensatable target could be an activity
            if (lastCompensatableTarget.TargetActivity != null && lastCompensatableTarget.TargetActivity is ICompensatableActivity)
            {
                lastCompensatableTarget.TargetActivity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler);
                context.CompensateActivity(lastCompensatableTarget.TargetActivity);
                return(true);
            } //or get the last compensatable "completed" context
            else if (lastCompensatableTarget.TargetExecutionInfo != null && lastCompensatableTarget.TargetExecutionContextManager != null)
            {
                ActivityExecutionContext revokedExecutionContext = lastCompensatableTarget.TargetExecutionContextManager.DiscardPersistedExecutionContext(lastCompensatableTarget.TargetExecutionInfo);

                //get the "first" compensatable child and compensate it
                if (revokedExecutionContext.Activity is ICompensatableActivity)
                {
                    revokedExecutionContext.Activity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler);
                    revokedExecutionContext.CompensateActivity(revokedExecutionContext.Activity);
                    return(true);
                }
                else if (revokedExecutionContext.Activity is CompositeActivity)
                {
                    //get the last compensatable child of the revoked context
                    Activity compensatableChild = GetLastCompensatableChild(revokedExecutionContext.Activity as CompositeActivity);
                    if (compensatableChild != null)
                    {
                        compensatableChild.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler);
                        revokedExecutionContext.CompensateActivity(compensatableChild);
                        return(true);
                    }
                    else// recursively, walk the context tree and keep revoking the compensatable contexts
                    {
                        return(TryCompensateLastCompletedChildActivity(revokedExecutionContext, revokedExecutionContext.Activity, statusChangeHandler, false));
                    }
                }
            }
            else if (lastCompensatableTarget.TargetExecutionContext != null) //or get the last compensatable "active" context
            {
                if (lastCompensatableTarget.TargetExecutionContext.Activity is CompositeActivity)
                {
                    //get the last compensatable child of the active context
                    Activity compensatableChild = GetLastCompensatableChild(lastCompensatableTarget.TargetExecutionContext.Activity as CompositeActivity);
                    if (compensatableChild != null)
                    {
                        compensatableChild.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler);
                        lastCompensatableTarget.TargetExecutionContext.CompensateActivity(compensatableChild);
                        return(true);
                    }
                    else // recursively, walk the context tree and keep revoking the compensatable contexts
                    {
                        return(TryCompensateLastCompletedChildActivity(lastCompensatableTarget.TargetExecutionContext, lastCompensatableTarget.TargetExecutionContext.Activity, statusChangeHandler, false));
                    }
                }
            }
            return(false);
        }
Example #8
0
        public void OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext context = sender as ActivityExecutionContext;

            if (context == null)
            {
                throw new ArgumentException("sender");
            }

            // waiting for primary activity to close
            if (e.Activity == context.Activity)
            {
                if (context.Activity.HasPrimaryClosed &&
                    !(bool)context.Activity.GetValue(FaultAndCancellationHandlingFilter.FaultProcessedProperty))
                {
                    context.Activity.SetValue(FaultAndCancellationHandlingFilter.FaultProcessedProperty, true);

                    if (context.Activity.WasExecuting &&
                        context.Activity.ExecutionResult == ActivityExecutionResult.Faulted &&
                        context.Activity.GetValue(ActivityExecutionContext.CurrentExceptionProperty) != null)
                    {
                        // execute exceptionHandlers, iff activity has transitioned from Executing to Faulting.
                        CompositeActivity exceptionHandlersActivity = FaultAndCancellationHandlingFilter.GetFaultHandlers(context.Activity);
                        if (exceptionHandlersActivity != null)
                        {
                            // listen for FaultHandler status change events
                            exceptionHandlersActivity.RegisterForStatusChange(Activity.ClosedEvent, this);

                            // execute exception handlers
                            context.ExecuteActivity(exceptionHandlersActivity);
                        }
                        else
                        {
                            // compensate completed children
                            if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                            {
                                SafeReleaseLockOnStatusChange(context); // no children to compensate...release lock on to the close status of the activity
                            }
                        }
                    }
                    else if (context.Activity.ExecutionResult == ActivityExecutionResult.Canceled)
                    {
                        // if primary activity is closed and outcome is canceled, then run the cancel handler
                        Activity cancelHandler = FaultAndCancellationHandlingFilter.GetCancellationHandler(context.Activity);
                        if (cancelHandler != null)
                        {
                            // execute the cancel handler
                            cancelHandler.RegisterForStatusChange(Activity.ClosedEvent, this);
                            context.ExecuteActivity(cancelHandler);
                        }
                        else
                        {
                            // run default compensation
                            if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                            {
                                SafeReleaseLockOnStatusChange(context); // release lock on to the close status of the activity
                            }
                        }
                    }
                    else // release lock on to the close status of the activity
                    {
                        SafeReleaseLockOnStatusChange(context);
                    }
                }
            }
            else if ((e.Activity is FaultHandlersActivity || e.Activity is CancellationHandlerActivity)
                     &&
                     (e.ExecutionStatus == ActivityExecutionStatus.Closed)
                     )
            {
                // remove subscriber
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);

                // fetch the exception , it would be null if it was handled
                if (context.Activity.GetValue(ActivityExecutionContext.CurrentExceptionProperty) != null)
                {
                    // the exception was not handled by exceptionHandlers.... do default exceptionHandling
                    // compesate completed children
                    if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                    {
                        SafeReleaseLockOnStatusChange(context); // no children to compensate.Release lock on to the close status of the activity
                    }
                }
                else// the exception was handled by the exceptionHandlers. Release lock on to the close status of the parent activity
                {
                    SafeReleaseLockOnStatusChange(context);
                }
            }
            else if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                // compensation of a child was in progress. // remove subscriber for this
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);

                // see if there are other children to be compensated
                if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    SafeReleaseLockOnStatusChange(context); // release lock on to the close status of the parent activity
                }
            }
        }
        private ActivityExecutionStatus CompensateTargetActivity(ActivityExecutionContext context)
        {
            Activity targetActivity       = null;
            Activity commonParentActivity = context.Activity;

            do
            {
                commonParentActivity = commonParentActivity.Parent;
                targetActivity       = commonParentActivity.GetActivityByName(this.TargetActivityName, true);
            } while (targetActivity == null);

            if (targetActivity is ICompensatableActivity &&
                targetActivity.ExecutionStatus == ActivityExecutionStatus.Closed &&
                targetActivity.ExecutionResult == ActivityExecutionResult.Succeeded)
            {
                // same execution context
                targetActivity.RegisterForStatusChange(Activity.ClosedEvent, this);
                context.CompensateActivity(targetActivity);
                return(context.Activity.ExecutionStatus);
            }
            else if (targetActivity.ExecutionStatus == ActivityExecutionStatus.Initialized)
            {
                // Template activity

                // walk through active contexts
                ActivityExecutionContextManager contextManager = context.ExecutionContextManager;
                foreach (ActivityExecutionContext activeContext in contextManager.ExecutionContexts)
                {
                    if (targetActivity.GetActivityByName(activeContext.Activity.QualifiedName, true) != null)
                    {
                        if (activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Compensating ||
                            activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Faulting ||
                            activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Canceling
                            )
                        {
                            return(context.Activity.ExecutionStatus);
                        }
                    }
                }

                // walk through all completed execution contexts
                for (int index = contextManager.CompletedExecutionContexts.Count - 1; index >= 0; index--)
                {
                    //only compensate direct child during explicit compensation
                    ActivityExecutionContextInfo completedActivityInfo = contextManager.CompletedExecutionContexts[index];
                    if (((completedActivityInfo.Flags & PersistFlags.NeedsCompensation) != 0))
                    {
                        ActivityExecutionContext revokedExecutionContext = contextManager.DiscardPersistedExecutionContext(completedActivityInfo);
                        if (revokedExecutionContext.Activity is ICompensatableActivity)
                        {
                            revokedExecutionContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, this);
                            revokedExecutionContext.CompensateActivity(revokedExecutionContext.Activity);
                        }
                        return(context.Activity.ExecutionStatus);
                    }
                }
            }
            else
            {
                // currently faulting, canceling, or compensating
                if (CompensationUtils.TryCompensateLastCompletedChildActivity(context, targetActivity, this))
                {
                    return(context.Activity.ExecutionStatus);
                }
            }
            return(ActivityExecutionStatus.Closed);
        }
Example #10
0
        public void OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext context = sender as ActivityExecutionContext;

            if (context == null)
            {
                throw new ArgumentException("sender");
            }
            if (e.Activity == context.Activity)
            {
                if (context.Activity.HasPrimaryClosed && !((bool)context.Activity.GetValue(FaultProcessedProperty)))
                {
                    context.Activity.SetValue(FaultProcessedProperty, true);
                    if ((!context.Activity.WasExecuting || (context.Activity.ExecutionResult != ActivityExecutionResult.Faulted)) || (context.Activity.GetValue(ActivityExecutionContext.CurrentExceptionProperty) == null))
                    {
                        if (context.Activity.ExecutionResult != ActivityExecutionResult.Canceled)
                        {
                            this.SafeReleaseLockOnStatusChange(context);
                        }
                        else
                        {
                            Activity cancellationHandler = GetCancellationHandler(context.Activity);
                            if (cancellationHandler != null)
                            {
                                cancellationHandler.RegisterForStatusChange(Activity.ClosedEvent, this);
                                context.ExecuteActivity(cancellationHandler);
                            }
                            else if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                            {
                                this.SafeReleaseLockOnStatusChange(context);
                            }
                        }
                    }
                    else
                    {
                        CompositeActivity faultHandlers = GetFaultHandlers(context.Activity);
                        if (faultHandlers != null)
                        {
                            faultHandlers.RegisterForStatusChange(Activity.ClosedEvent, this);
                            context.ExecuteActivity(faultHandlers);
                        }
                        else if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                        {
                            this.SafeReleaseLockOnStatusChange(context);
                        }
                    }
                }
            }
            else if (((e.Activity is FaultHandlersActivity) || (e.Activity is CancellationHandlerActivity)) && (e.ExecutionStatus == ActivityExecutionStatus.Closed))
            {
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                if (context.Activity.GetValue(ActivityExecutionContext.CurrentExceptionProperty) == null)
                {
                    this.SafeReleaseLockOnStatusChange(context);
                }
                else if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    this.SafeReleaseLockOnStatusChange(context);
                }
            }
            else if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    this.SafeReleaseLockOnStatusChange(context);
                }
            }
        }