TryCatch.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 / NetFx40 / System.Activities / System / Activities / Statements / TryCatch.cs / 1305376 / TryCatch.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.Activities.Statements 
{
    using System; 
    using System.Activities; 
    using System.Activities.Runtime;
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.Collections;
    using System.Runtime.Serialization; 
    using System.Windows.Markup;
 
    public sealed class TryCatch : NativeActivity 
    {
        CatchList catches; 
        Collection variables;

        Variable state;
 
        FaultCallback exceptionFromCatchOrFinallyHandler;
 
        internal const string FaultContextId = "{35ABC8C3-9AF1-4426-8293-A6DDBB6ED91D}"; 

        public TryCatch() 
            : base()
        {
            this.state = new Variable();
        } 

        public Collection Variables 
        { 
            get
            { 
                if (this.variables == null)
                {
                    this.variables = new ValidatingCollection
                    { 
                        // disallow null values
                        OnAddValidationCallback = item => 
                        { 
                            if (item == null)
                            { 
                                throw FxTrace.Exception.ArgumentNull("item");
                            }
                        }
                    }; 
                }
                return this.variables; 
            } 
        }
 
        [DefaultValue(null)]
        [DependsOn("Variables")]
        public Activity Try
        { 
            get;
            set; 
        } 

        [DependsOn("Try")] 
        public Collection Catches
        {
            get
            { 
                if (this.catches == null)
                { 
                    this.catches = new CatchList(); 
                }
                return this.catches; 
            }
        }

        [DefaultValue(null)] 
        [DependsOn("Catches")]
        public Activity Finally 
        { 
            get;
            set; 
        }

        FaultCallback ExceptionFromCatchOrFinallyHandler
        { 
            get
            { 
                if (this.exceptionFromCatchOrFinallyHandler == null) 
                {
                    this.exceptionFromCatchOrFinallyHandler = new FaultCallback(OnExceptionFromCatchOrFinally); 
                }

                return this.exceptionFromCatchOrFinallyHandler;
            } 
        }
 
        protected override void CacheMetadata(NativeActivityMetadata metadata) 
        {
            if (Try != null) 
            {
                metadata.AddChild(this.Try);
            }
 
            if (this.Finally != null)
            { 
                metadata.AddChild(this.Finally); 
            }
 
            Collection delegates = new Collection();

            if (this.catches != null)
            { 
                foreach (Catch item in this.catches)
                { 
                    ActivityDelegate catchDelegate = item.GetAction(); 
                    if (catchDelegate != null)
                    { 
                        delegates.Add(catchDelegate);
                    }
                }
            } 

            metadata.AddImplementationVariable(this.state); 
 
            metadata.SetDelegatesCollection(delegates);
 
            metadata.SetVariablesCollection(this.Variables);

            if (this.Finally == null && this.Catches.Count == 0)
            { 
                metadata.AddValidationError(SR.CatchOrFinallyExpected(this.DisplayName));
            } 
        } 

        internal static Catch FindCatchActivity(Type typeToMatch, IList catches) 
        {
            foreach (Catch item in catches)
            {
                if (item.ExceptionType == typeToMatch) 
                {
                    return item; 
                } 
            }
 
            return null;
        }

        protected override void Execute(NativeActivityContext context) 
        {
            this.state.Set(context, new TryCatchState()); 
            if (this.Try != null) 
            {
                context.ScheduleActivity(this.Try, new CompletionCallback(OnTryComplete), new FaultCallback(OnExceptionFromTry)); 
            }
            else
            {
                OnTryComplete(context, null); 
            }
        } 
 
        protected override void Cancel(NativeActivityContext context)
        { 
            TryCatchState state = this.state.Get(context);
            if (!state.SuppressCancel)
            {
                context.CancelChildren(); 
            }
        } 
 
        void OnTryComplete(NativeActivityContext context, ActivityInstance completedInstance)
        { 
            TryCatchState state = this.state.Get(context);

            // We only allow the Try to be canceled.
            state.SuppressCancel = true; 

            if (state.CaughtException != null) 
            { 
                Catch toSchedule = FindCatch(state.CaughtException.Exception);
 
                if (toSchedule != null)
                {
                    state.ExceptionHandled = true;
                    if (toSchedule.GetAction() != null) 
                    {
                        context.Properties.Add(FaultContextId, state.CaughtException, true); 
                        toSchedule.ScheduleAction(context, state.CaughtException.Exception, new CompletionCallback(OnCatchComplete), this.ExceptionFromCatchOrFinallyHandler); 
                        return;
                    } 
                }
            }

            OnCatchComplete(context, null); 
        }
 
        void OnExceptionFromTry(NativeActivityFaultContext context, Exception propagatedException, ActivityInstance propagatedFrom) 
        {
            if(propagatedFrom.IsCancellationRequested) 
            {
                if (TD.TryCatchExceptionDuringCancelationIsEnabled())
                {
                    TD.TryCatchExceptionDuringCancelation(this.DisplayName); 
                }
 
                // The Try activity threw an exception during Cancel; abort the workflow 
                context.Abort(propagatedException);
                context.HandleFault(); 
            }
            else
            {
                Catch catchHandler = FindCatch(propagatedException); 
                if (catchHandler != null)
                { 
                    if (TD.TryCatchExceptionFromTryIsEnabled()) 
                    {
                        TD.TryCatchExceptionFromTry(this.DisplayName, propagatedException.GetType().ToString()); 
                    }

                    context.CancelChild(propagatedFrom);
                    TryCatchState state = this.state.Get(context); 
                    state.CaughtException = context.CreateFaultContext();
                    context.HandleFault(); 
                } 
            }
        } 

        void OnCatchComplete(NativeActivityContext context, ActivityInstance completedInstance)
        {
            // Start suppressing cancel for the finally activity 
            TryCatchState state = this.state.Get(context);
            state.SuppressCancel = true; 
 
            if (completedInstance != null && completedInstance.State != ActivityInstanceState.Closed)
            { 
                state.ExceptionHandled = false;
            }

            context.Properties.Remove(FaultContextId); 

            if (this.Finally != null) 
            { 
                context.ScheduleActivity(this.Finally, new CompletionCallback(OnFinallyComplete), this.ExceptionFromCatchOrFinallyHandler);
            } 
            else
            {
                OnFinallyComplete(context, null);
            } 
        }
 
        void OnFinallyComplete(NativeActivityContext context, ActivityInstance completedInstance) 
        {
            TryCatchState state = this.state.Get(context); 
            if (context.IsCancellationRequested && !state.ExceptionHandled)
            {
                context.MarkCanceled();
            } 
        }
 
        void OnExceptionFromCatchOrFinally(NativeActivityFaultContext context, Exception propagatedException, ActivityInstance propagatedFrom) 
        {
            if (TD.TryCatchExceptionFromCatchOrFinallyIsEnabled()) 
            {
                TD.TryCatchExceptionFromCatchOrFinally(this.DisplayName);
            }
 
            // We allow cancel through if there is an exception from the catch or finally
            TryCatchState state = this.state.Get(context); 
            state.SuppressCancel = false; 
        }
 
        Catch FindCatch(Exception exception)
        {
            Type exceptionType = exception.GetType();
            Catch potentialCatch = null; 

            foreach (Catch catchHandler in this.Catches) 
            { 
                if (catchHandler.ExceptionType == exceptionType)
                { 
                    // An exact match
                    return catchHandler;
                }
                else if (catchHandler.ExceptionType.IsAssignableFrom(exceptionType)) 
                {
                    if (potentialCatch != null) 
                    { 
                        if (catchHandler.ExceptionType.IsSubclassOf(potentialCatch.ExceptionType))
                        { 
                            // The new handler is more specific
                            potentialCatch = catchHandler;
                        }
                    } 
                    else
                    { 
                        potentialCatch = catchHandler; 
                    }
                } 
            }

            return potentialCatch;
        } 

        [DataContract] 
        internal class TryCatchState 
        {
            [DataMember(EmitDefaultValue = false)] 
            public bool SuppressCancel
            {
                get;
                set; 
            }
 
            [DataMember(EmitDefaultValue = false)] 
            public FaultContext CaughtException
            { 
                get;
                set;
            }
 
            [DataMember(EmitDefaultValue = false)]
            public bool ExceptionHandled 
            { 
                get;
                set; 
            }
        }

        class CatchList : ValidatingCollection 
        {
            public CatchList() 
                : base() 
            {
                this.OnAddValidationCallback = item => 
                {
                    if (item == null)
                    {
                        throw FxTrace.Exception.ArgumentNull("item"); 
                    }
                }; 
            } 

            protected override void InsertItem(int index, Catch item) 
            {
                if (item == null)
                {
                    throw FxTrace.Exception.ArgumentNull("item"); 
                }
 
                Catch existingCatch = TryCatch.FindCatchActivity(item.ExceptionType, this.Items); 

                if (existingCatch != null) 
                {
                    throw FxTrace.Exception.Argument("item", SR.DuplicateCatchClause(item.ExceptionType.FullName));
                }
 
                base.InsertItem(index, item);
            } 
 
            protected override void SetItem(int index, Catch item)
            { 
                if (item == null)
                {
                    throw FxTrace.Exception.ArgumentNull("item");
                } 

                Catch existingCatch = TryCatch.FindCatchActivity(item.ExceptionType, this.Items); 
 
                if (existingCatch != null && !object.ReferenceEquals(this[index], existingCatch))
                { 
                    throw FxTrace.Exception.Argument("item", SR.DuplicateCatchClause(item.ExceptionType.FullName));
                }

                base.SetItem(index, item); 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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