一、多播委托(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<Product> func1 = new Func<Product>(productFactory.MakePizza);
Func<Product> func2 = new Func<Product>(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<Product> 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 ;
}
}
}
标签:Product,委托,c#,System,高级,Student,using,Action,new
From: https://blog.csdn.net/weixin_66365687/article/details/139395878