FaultHandlingFilter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Filters / FaultHandlingFilter.cs / 1305376 / FaultHandlingFilter.cs

                            namespace System.Workflow.ComponentModel 
{
    using System;
    using System.Collections;
    using System.Diagnostics; 
    using System.ComponentModel;
    using System.Collections.Generic; 
    using System.Workflow.ComponentModel.Design; 

    internal sealed class FaultAndCancellationHandlingFilter : ActivityExecutionFilter, IActivityEventListener 
    {
        public static DependencyProperty FaultProcessedProperty = DependencyProperty.RegisterAttached("FaultProcessed", typeof(bool), typeof(FaultAndCancellationHandlingFilter), new PropertyMetadata(false));

        #region Execute Signal 

        public override ActivityExecutionStatus Execute(Activity activity, ActivityExecutionContext executionContext) 
        { 
            if (activity == null)
                throw new ArgumentNullException("activity"); 
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");

            if (! (activity is CompositeActivity)) 
                throw new InvalidOperationException("activity");
 
            executionContext.Activity.HoldLockOnStatusChange(this); 
            return base.Execute(activity, executionContext);
        } 

        public override ActivityExecutionStatus HandleFault(Activity activity, ActivityExecutionContext executionContext, Exception exception)
        {
            if (activity.HasPrimaryClosed != true) 
                return base.HandleFault(activity, executionContext, exception);
 
            //We are handed fault again. Quiten Fault & Cancellation Handlers if any running. 
            Activity handlersActivity = FaultAndCancellationHandlingFilter.GetFaultHandlers(executionContext.Activity);
            if (handlersActivity != null && (handlersActivity.ExecutionStatus != ActivityExecutionStatus.Closed && handlersActivity.ExecutionStatus != ActivityExecutionStatus.Initialized)) 
            {
                if(handlersActivity.ExecutionStatus == ActivityExecutionStatus.Executing)
                   executionContext.CancelActivity(handlersActivity);
 
                return ActivityExecutionStatus.Faulting;
            } 
            else 
            {
                handlersActivity = FaultAndCancellationHandlingFilter.GetCancellationHandler(executionContext.Activity); 

                if (handlersActivity != null && (handlersActivity.ExecutionStatus != ActivityExecutionStatus.Closed && handlersActivity.ExecutionStatus != ActivityExecutionStatus.Initialized))
                {
                    if(handlersActivity.ExecutionStatus == ActivityExecutionStatus.Executing) 
                       executionContext.CancelActivity(handlersActivity);
                    return ActivityExecutionStatus.Faulting; 
                } 
            }
 
            if ((bool)activity.GetValue(FaultAndCancellationHandlingFilter.FaultProcessedProperty))
               SafeReleaseLockOnStatusChange(executionContext);

            return base.HandleFault(activity, executionContext, exception); 
        }
 
        #endregion 

        #region IActivityEventListener Members 

        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
            } 
        }
 
        void SafeReleaseLockOnStatusChange(ActivityExecutionContext context) 
        {
            try 
            {
                context.Activity.ReleaseLockOnStatusChange(this);
            }
            catch(Exception) 
            {
                context.Activity.RemoveProperty(FaultAndCancellationHandlingFilter.FaultProcessedProperty); 
                throw; 
            }
        } 
        #endregion

        #region Helper Methods
 
        internal static CompositeActivity GetFaultHandlers(Activity activityWithExceptionHandlers)
        { 
            CompositeActivity exceptionHandlers = null; 
            CompositeActivity compositeActivity = activityWithExceptionHandlers as CompositeActivity;
            if (compositeActivity != null) 
            {
                foreach (Activity activity in ((ISupportAlternateFlow)compositeActivity).AlternateFlowActivities)
                {
                    if (activity is FaultHandlersActivity) 
                    {
                        exceptionHandlers = activity as CompositeActivity; 
                        break; 
                    }
                } 
            }
            return exceptionHandlers;
        }
        internal static Activity GetCancellationHandler(Activity activityWithCancelHandler) 
        {
            Activity cancelHandler = null; 
            CompositeActivity compositeActivity = activityWithCancelHandler as CompositeActivity; 
            if (compositeActivity != null)
            { 
                foreach (Activity activity in ((ISupportAlternateFlow)compositeActivity).AlternateFlowActivities)
                {
                    if (activity is CancellationHandlerActivity)
                    { 
                        cancelHandler = activity;
                        break; 
                    } 
                }
            } 
            return cancelHandler;
        }
        #endregion
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK