天天看點

轉-C#多點傳播委托因異常而終止的解決方案

#define UseEvent
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MultiDelegateException
{

    class Program
    {
        private static event Action multiEvent;
        //定義一個委托
        private static Action multiDelegate;

        private static GetResult getResultDelegate;

        static void Main(string[] args)
        {
#if UseDelegate

            //建立多點傳播委托
            multiDelegate = MultiDelegate.Func1;
            multiDelegate += MultiDelegate.Func2;

            //調用委托,觀察結果
            try
            {
                multiDelegate();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.WriteLine("---------------------------分割線------------------------------");
            //手動疊代委托方法清單,可以處理抛出異常後委托鍊終止執行的問題
            //定義方法清單數組,使用GetInvocationList()  
            //注意使用的是Delegate類,不是delegate關鍵字  
            Delegate[] myDelegates = multiDelegate.GetInvocationList();
            foreach (var @delegate in myDelegates)
            {
                var delegateItem = (Action) @delegate;
                //分别調用委托
                try
                {
                    delegateItem();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
#elif UseEvent
            //依次注冊事件
            multiEvent += MultiDelegate.Func1;
            multiEvent += MultiDelegate.Func2;

            //調用事件,觀察結果
            try
            {
                multiEvent();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.WriteLine("---------------------------分割線------------------------------");
            //手動疊代委托方法清單,可以處理抛出異常後委托鍊終止執行的問題
            //定義方法清單數組,使用GetInvocationList()  
            //注意使用的是Delegate類,不是delegate關鍵字  

            Delegate[] myDelegates = multiEvent.GetInvocationList();
            foreach (var @delegate in myDelegates)
            {
                var delegateItem = @delegate as Action;
                try
                {
                    delegateItem();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
#endif
            Console.WriteLine("---------------------------分割線------------------------------");
            getResultDelegate = MultiDelegate.GetOne;
            getResultDelegate += MultiDelegate.GetTwo;

            Console.WriteLine("直接調用委托傳回的一般是最後一個方法的傳回值:" + getResultDelegate());

            //手動疊代委托方法清單,可以擷取并處理每個委托的傳回值
            //定義方法清單數組,使用GetInvocationList()  
            //注意使用的是Delegate類,不是delegate關鍵字 
            int sum = 0;
            Delegate[] resultDelegates = getResultDelegate.GetInvocationList();
            foreach (var @delegate in resultDelegates)
            {
                var delegateItem = @delegate as GetResult;
                sum += delegateItem();
                Console.WriteLine("擷取單個委托的傳回值:" + delegateItem());
            }
            Console.WriteLine("多個委托的傳回值總和:" + sum);

            Console.ReadLine();
        }
    }

    /// <summary>
    /// 帶有傳回值的委托
    /// </summary>
    /// <returns></returns>
    public delegate int GetResult();

    class MultiDelegate
    {
        /// <summary>
        /// 會抛出異常的方法1
        /// </summary>
        public static void Func1()
        {
            Console.WriteLine("方法1,會抛出異常!");
            throw new Exception("抛出異常!");
        }

        /// <summary>
        /// 正常方法2
        /// </summary>
        public static void Func2()
        {
            Console.WriteLine("方法2");
        }

        /// <summary>
        /// 帶有傳回值的函數
        /// </summary>
        /// <returns></returns>
        public static int GetOne()
        {
            return 1;
        }

        /// <summary>
        /// 帶有傳回值的函數
        /// </summary>
        /// <returns></returns>
        public static int GetTwo()
        {
            return 2;
        }
    }

}