ExceptionWrapper.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 / wpf / src / Base / MS / Internal / Threading / ExceptionWrapper.cs / 1305600 / ExceptionWrapper.cs

                            // 
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
// 
// 
// Description:
// 
//---------------------------------------------------------------------------- 

 
using Microsoft.Win32;                       // Registry & ComponentDispatcher & MSG
using System.Security;                       // CAS
using System.Security.Permissions;           // Registry permissions
using System.Runtime.InteropServices;        // SEHException 
using System.Diagnostics;                    // Debug & Debugger
using System.Threading; 
using MS.Internal.Threading;                // ExceptionFilterHelper 
using MS.Internal.WindowsBase;
 
namespace System.Windows.Threading
{
    /// 
    /// Class for Filtering and Catching Exceptions 
    /// 
    internal class ExceptionWrapper 
    { 
        internal ExceptionWrapper()
        { 
            _exceptionFilterHelper = new ExceptionFilterHelper(
                    new InternalRealCallDelegate(InternalRealCall),
                    new FilterExceptionDelegate(FilterException),
                    new CatchExceptionDelegate(CatchException) ); 
        }
 
        // Helper for exception filtering: 
        // The real impl is in Base\MS\Internal\Threading\ExceptionFilterHelper.vb
        public object TryCatchWhen(object source, Delegate callback, object args, int numArgs, Delegate catchHandler) 
        {
            return _exceptionFilterHelper.TryCatchWhen(source, callback, args, numArgs, catchHandler);

//            object result = null; 
//            try
//            { 
//                result = InternalRealCall(callback, args, numArgs); 
//            }
//            catch(Exception e) WHEN FilterException( Exception e ); 
//            {
//                if (e is NullReferenceException || e is SEHException)
//                   throw;
//                else 
//                    if( ! CatchException(source, e) )
//                        throw; 
//            } 
//            return result;
        } 

        private object InternalRealCall(Delegate callback, object args, int numArgs)
        {
            object result = null; 

            Debug.Assert(numArgs == 0 || // old API, no args 
                         numArgs == 1 || // old API, 1 arg, the args param is it 
                         numArgs == -1); // new API, any number of args, the args param is an array of them
 
            // Support the fast-path for certain 0-param and 1-param delegates, even
            // of an arbitrary "params object[]" is passed.
            int numArgsEx = numArgs;
            object singleArg = args; 
            if(numArgs == -1)
            { 
                object[] argsArr = (object[])args; 
                if (argsArr == null || argsArr.Length == 0)
                { 
                    numArgsEx = 0;
                }
                else if(argsArr.Length == 1)
                { 
                    numArgsEx = 1;
                    singleArg = argsArr[0]; 
                } 
            }
 
            // Special-case delegates that we know about to avoid the
            // expensive DynamicInvoke call.
            if(numArgsEx == 0)
            { 
                Action action = callback as Action;
                if (action != null) 
                { 
                    action();
                } 
                else
                {
                    Dispatcher.ShutdownCallback shutdownCallback = callback as Dispatcher.ShutdownCallback;
                    if(shutdownCallback != null) 
                    {
                        shutdownCallback(); 
                    } 
                    else
                    { 
                        // The delegate could return anything.
                        result = callback.DynamicInvoke();
                    }
                } 
            }
            else if(numArgsEx == 1) 
            { 
                DispatcherOperationCallback dispatcherOperationCallback = callback as DispatcherOperationCallback;
                if(dispatcherOperationCallback != null) 
                {
                    result = dispatcherOperationCallback(singleArg);
                }
                else 
                {
                    SendOrPostCallback sendOrPostCallback = callback as SendOrPostCallback; 
                    if(sendOrPostCallback != null) 
                    {
                        sendOrPostCallback(singleArg); 
                    }
                    else
                    {
                        if(numArgs == -1) 
                        {
                            // Explicitly pass an object[] to DynamicInvoke so that 
                            // it will not try to wrap the arg in another object[]. 
                            result = callback.DynamicInvoke((object[])args);
                        } 
                        else
                        {
                            // By pass the args parameter as a single object,
                            // DynamicInvoke will wrap it in an object[] due to the 
                            // params keyword.
                            result = callback.DynamicInvoke(args); 
                        } 
                    }
                } 
            }
            else
            {
                // Explicitly pass an object[] to DynamicInvoke so that 
                // it will not try to wrap the arg in another object[].
                result = callback.DynamicInvoke((object[])args); 
            } 

            return result; 
        }

        private bool FilterException(object source, Exception e)
        { 
            // If we have a Catch handler we should catch the exception
            // unless the Filter handler says we shouldn't. 
            bool shouldCatch = (null != Catch); 
            if(null != Filter)
            { 
                shouldCatch = Filter(source, e);
            }
            return shouldCatch;
        } 

        // This returns false when caller should rethrow the exception. 
        // true means Exception is "handled" and things just continue on. 
        private bool CatchException(object source, Exception e, Delegate catchHandler)
        { 
            if (catchHandler != null)
            {
                if(catchHandler is DispatcherOperationCallback)
                { 
                    ((DispatcherOperationCallback)catchHandler)(null);
                } 
                else 
                {
                    catchHandler.DynamicInvoke(null); 
                }
            }

            if(null != Catch) 
                return Catch(source, e);
 
            return false; 
        }
 
        /// 
        /// Exception Catch Handler Delegate
        ///  Returns true if the exception is "handled"
        ///  Returns false if the caller should rethow the exception. 
        /// 
        public delegate bool CatchHandler(object source, Exception e); 
 
        /// 
        /// Exception Catch Handler 
        ///  Returns true if the exception is "handled"
        ///  Returns false if the caller should rethow the exception.
        /// 
        public event CatchHandler Catch; 

        public delegate bool FilterHandler(object source, Exception e); 
        public event FilterHandler Filter; 

        private ExceptionFilterHelper _exceptionFilterHelper; 
    }
}

 

// 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