委托系列06-多播委托


一、多播委托的介绍

二、代码准备

    /// 
    /// 多播委托
    /// 
    public class CustomMulticastDelegation
    {
        private void DoNothing()
        {
            Console.WriteLine("This is DoNothing");
        }

        private void DoNothing(int i)
        {
            Console.WriteLine("This is DoNothing");
        }

        private void DoNothingInt(int i)
        {
            Console.WriteLine("This is DoNothingInt");
        }
        private void DoNothingIntAndString(int i, string j)
        {
            Console.WriteLine("This is DoNothingIntAndString");
        }

        private static void DoNothingStatic()
        {
            Console.WriteLine("This is DoNothingStatic");
        }
    }

Student类:

    /// 
    /// 学生类
    /// 
    public class Student
    {
        public void Study()
        {
            Console.WriteLine("Student类Study方法执行。。。");
        }

        public static void StudyAdvanced()
        {
            Console.WriteLine("Student类StudyAdvanced方法执行。。。");
        }
    }

三、多播委托的使用

1、创建委托

        public void Show()
        {
            Action action = new Action(DoNothing);
        }

2、注册方法

        public void Show()
        {
            Action action = new Action(DoNothing);
            action += DoNothingStatic;
            action += new Student().Study;
            action += Student.StudyAdvanced;
            action += DoNothing;
            action += () =>
            {
                Console.WriteLine("this is 拉姆达表达式。。。");
            };
        }

3、执行委托

        public void Show()
        {
            Action action = new Action(DoNothing);
            action += DoNothingStatic;
            action += new Student().Study;
            action += Student.StudyAdvanced;
            action += DoNothing;
            action += () =>
            {
                Console.WriteLine("this is 拉姆达表达式。。。");
            };
            action.Invoke();
        }

4、输出结果

5、总结

??多播委托通过通过+= 把多个方法添加到这个委托中去;形成一个方法的执行链;执行委托的时候,按照添加方法的顺序,依次去执行委托。

四、多播委托多线程执行

??如果多播委托的多个方法需要通过多线程执行的话,按照action.BeginInvoke()是不行的,我们可以通过下面这种方式

正确方式:

        public void Show()
        {
            Action action = new Action(DoNothing);
            action += DoNothingStatic;
            action += new Student().Study;
            action += Student.StudyAdvanced;
            action += DoNothing;
            action += () =>
            {
                Console.WriteLine($"this is 拉姆达表达式。。。,线程ID{Thread.CurrentThread.ManagedThreadId}");
            };
            {               
                //action.BeginInvoke();//开启一个新的线程 去执行委托---注册有多个方法的委托,不能使用BeginInvoke 
                foreach (Action item in action.GetInvocationList())
                {
                    //注意:.Net Core不支持BeginInvoke()
                    //item.BeginInvoke(null, null);
                    Task.Run(item);
                }
            }
        }

输出结果:

五、多播委托的取消注册

代码:

        public void Show()
        {
            Action action = new Action(DoNothing);
            action += DoNothingStatic;
            action += new Student().Study;
            action += Student.StudyAdvanced;
            action += DoNothing;
            action += () =>
            {
                Console.WriteLine($"this is 拉姆达表达式。。。,线程ID{Thread.CurrentThread.ManagedThreadId}");
            };
            {               
                //action.BeginInvoke();//开启一个新的线程 去执行委托---注册有多个方法的委托,不能使用BeginInvoke 
                //foreach (Action item in action.GetInvocationList())
                //{
                //    //注意:.Net Core不支持BeginInvoke()
                //    //item.BeginInvoke(null, null);
                //    Task.Run(item);
                //}
            }

            action -= DoNothing;
            action -= new Student().Study; //没有移除掉:因为不是同一个实例
            action -= () => //没有移除:  其实是因为不同同一个方法---lambda表达式--在底层会生成不同的方法
             {
                 Console.WriteLine("this is 拉姆达表达式。。。");
             };
            action.Invoke();
        }

输出结果:

结论:

  • 1、new Student().Study这种方式,因为注册和取消是两个对象,所以取消没有生效。
  • 2、注册和取消Lambada表达式并不是同一个方法。因为Lambada表达式在底层会创建一个方法,注册和取消的两个方法名不一致,所以取消没有生效。

相关