一、多播委托(multicast)&& 单播委托
一个委托内部封装不止一个方法
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Threading;
- namespace six_multicast
- {
- internal class Program
- {
- static void Main(string[] args)
- {
- Student student = new Student() { Id=1,PenColor = ConsoleColor.Yellow};
- Student student2 = new Student() { Id = 2,PenColor = ConsoleColor.Red};
- Student student3 = new Student() { Id = 3, PenColor = ConsoleColor.Green };
-
- Action action1 = new Action(student.DoHomeWork);
- Action action2 = new Action(student2.DoHomeWork);
- Action action3 = new Action(student3.DoHomeWork);
-
- //单播
- action1.Invoke();
- action2.Invoke();
- action3.Invoke();
-
- //多播
- action1 += action2;
- action1 += action3;
-
- action1.Invoke();
- }
- }
- class Student
- {
- public int Id { get; set; }
- public ConsoleColor PenColor { get; set; }
-
- public void DoHomeWork()
- {
- for (int i = 0; i < 5; i++)
- {
- Console.ForegroundColor = this.PenColor;
- Console.WriteLine("Student is {0} do homework {1} hour(s)", this.Id, i);
- Thread.Sleep(1000);
- }
- }
- }
-
- }
二、同步调用
每一个允许的程序是一个进程(Process)
每个进程可以有多个线程(Thread)
同步调用是在一个线程里
串行==同步==单线程
同步调用三种形式
1、直接同步调用
2、单播委托的间接调用
3、多播委托的间接调用
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Threading;
-
- namespace six_multicast
- {
- internal class Program
- {
- static void Main(string[] args)
- {
- Student student = new Student() { Id=1,PenColor = ConsoleColor.Yellow};
- Student student2 = new Student() { Id = 2,PenColor = ConsoleColor.Red};
- Student student3 = new Student() { Id = 3, PenColor = ConsoleColor.Green };
-
- Action action1 = new Action(student.DoHomeWork);
- Action action2 = new Action(student2.DoHomeWork);
- Action action3 = new Action(student3.DoHomeWork);
- //同步调用
- //在一根主线程上面执行(创建对象),当有方法执行的时候就去执行方法,然后继续执行主线程,最后主线程还有些事情要做
- //直接调用
- student.DoHomeWork();
- student2.DoHomeWork();
- student3.DoHomeWork();
-
- //单播(单波委托的间接调用)
- action1.Invoke();
- action2.Invoke();
- action3.Invoke();
-
- //多播(多播委托的间接调用)
- action1 += action2;
- action1 += action3;
-
- action1.Invoke();
-
-
- for (int i = 0; i < 10; i++)
- {
- Console.ForegroundColor = ConsoleColor.Cyan;
- Console.WriteLine("Main thread {0}", i);
- Thread.Sleep(1000);
- }
- }
- }
- class Student
- {
- public int Id { get; set; }
- public ConsoleColor PenColor { get; set; }
-
- public void DoHomeWork()
- {
- for (int i = 0; i < 5; i++)
- {
- Console.ForegroundColor = this.PenColor;
- Console.WriteLine("Student is {0} do homework {1} hour(s)", this.Id, i);
- Thread.Sleep(1000);
- }
- }
- }
-
- }
三、异步调用
同时进行,多个线程,底层原理=多线程
并行=异步=多线程
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Threading;
- namespace six_multicast
- {
- internal class Program
- {
- static void Main(string[] args)
- {
- Student student = new Student() { Id=1,PenColor = ConsoleColor.Yellow};
- Student student2 = new Student() { Id = 2,PenColor = ConsoleColor.Red};
- Student student3 = new Student() { Id = 3, PenColor = ConsoleColor.Green };
-
- Action action1 = new Action(student.DoHomeWork);
- Action action2 = new Action(student2.DoHomeWork);
- Action action3 = new Action(student3.DoHomeWork);
-
- //异步调用(多个线程争抢一个资源,会起冲突)
- //显示异步掉用(老方式)
- Thread thread = new Thread(new ThreadStart(student.DoHomeWork));
- Thread thread2 = new Thread(new ThreadStart(student2.DoHomeWork));
- Thread thread3 = new Thread(new ThreadStart(student3.DoHomeWork));
-
- thread.Start();
- thread2.Start();
- thread3.Start();
- //显示异步调用(新方式)
- Task task = new Task(new Action(student.DoHomeWork));
- Task task1 = new Task(new Action(student2.DoHomeWork));
- Task task2 = new Task(new Action(student3.DoHomeWork));
-
- task.Start();
- task1.Start();
- task2.Start();
- //隐式异步调用
- action1.BeginInvoke(null, null);
- action2.BeginInvoke(null, null);
- action3.BeginInvoke(null, null);
-
-
- for (int i = 0; i < 10; i++)
- {
- Console.ForegroundColor = ConsoleColor.Cyan;
- Console.WriteLine("Main thread {0}", i);
- Thread.Sleep(1000);
- }
- }
- }
- class Student
- {
- public int Id { get; set; }
- public ConsoleColor PenColor { get; set; }
-
- public void DoHomeWork()
- {
- for (int i = 0; i < 5; i++)
- {
- Console.ForegroundColor = this.PenColor;
- Console.WriteLine("Student is {0} do homework {1} hour(s)", this.Id, i);
- Thread.Sleep(1000);
- }
- }
- }
-
- }
总结:
应该慎重的使用委托
对于为什么会造成内存泄漏和程序性能下降原因
委托会引用一个方法,这个方法如果是一个实例方法的话,那么这个方法必定会隶属于一个对象,你拿一个委托引用了这个方法,那么这个对象就必须存在于内存当中,即便是没有其他的引用变量引用这个对象,因为你一释放这个内存,委托就不能够间接去调用对象的方法,所以所委托有可能造成内存泄漏,随着泄漏的内存越来越多,程序就会崩溃
使用异步会导致出现多个线程争抢资源的情况,会出现冲突,可以加上线程锁,另外,应该合适的使用接口interface取代一些对委托的使用
下面两个分别是使用接口interface与使用委托delegate,最终的实现都是一样
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace six_InterfaceDelegate
- {
- internal class Program
- {
- static void Main(string[] args)
- {
- WrapFactory wrapFactory = new WrapFactory();
- IProductFactory MakePizza = new MakePizza();
- IProductFactory MakeCar = new MakeCar();
-
- Box box = wrapFactory.ProductFactory(MakePizza);
- Box box2 = wrapFactory.ProductFactory(MakeCar);
-
- Console.WriteLine(box.Product.Name);
- Console.WriteLine(box2.Product.Name);
- }
- }
-
- interface IProductFactory
- {
- Product Make();
- }
- class MakePizza : IProductFactory
- {
- public Product Make()
- {
- Product product = new Product();
- product.Name = "Pizza";
- return product;
- }
- }
-
- class MakeCar : IProductFactory
- {
- public Product Make()
- {
- Product product = new Product();
- product.Name = "Car";
- return product;
- }
- }
- class Product
- {
- public string Name { get; set; }
- }
-
- class Box
- {
- public Product Product { get; set; }
- }
-
- class WrapFactory
- {
- public Box ProductFactory(IProductFactory productFactory)
- {
- Box box = new Box();
- Product product = productFactory.Make();
- box.Product = product;
- return box;
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- /*
- 演示了如何使用委托和模板方法来包装产品
- */
- namespace four_GreateDelegate2
- {
- internal class Program
- {
- static void Main(string[] args)
- {
-
- ProductFactory productFactory = new ProductFactory();
-
- WrapFactory wrapFactory = new WrapFactory();
-
- Func
func1 = new Func(productFactory.MakePizza); - Func
func2 = new Func(productFactory.MakeToCar); -
-
-
- Box box1 = wrapFactory.WrapProduct(func1);
- Box box2 = wrapFactory.WrapProduct(func2);
-
- Console.WriteLine(box1.Product.Name);
- Console.WriteLine(box2.Product.Name);
-
- }
- }
-
- class Product//产品
- {
- public string Name { get; set; }
- }
-
- class Box//箱子
- {
- public Product Product { get; set; }
- }
-
- class WrapFactory
- {
-
- public Box WrapProduct(Func
getProduct ) - {
- Box box = new Box();
-
- Product product = getProduct.Invoke();
-
- box.Product = product;
-
- return box;
- }
- }
-
- class ProductFactory
- {
- public Product MakePizza()
- {
-
- Product product = new Product();
- product.Name = "Pizza";
- return product;
- }
-
- public Product MakeToCar()
- {
- Product product = new Product();
- product.Name = "Toy Car";
- return product ;
- }
- }
- }