委托系列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表达式在底层会创建一个方法,注册和取消的两个方法名不一致,所以取消没有生效。