示例:回调方法
(也称作好莱坞方法)
演员去面试,给导演留了名片
导演说如果选中他,会给他打电话的
using System;
namespace CallBack
{
class Program
{
static void Main(string[] args)
{
//创建工厂实例
ProductFactory productFactory = new ProductFactory(); //创建产品工厂的实例
WrapFactory wrapFactory = new WrapFactory(); //创建包装工厂的实例
//用委托封装生产产品的方法
Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
//创建委托1,用来封装产品工厂类中生产披萨的方法
Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
//创建委托1,用来封装产品工厂类中生产小汽车的方法
Logger logger = new Logger(); //创建记录者类的实例
Action<Product> log = new Action<Product>(logger.Log); //
//使用模板方法
Box box1 = wrapFactory.WrapProduct(func1,log); //使用模板方法,生产并包装披萨
Box box2 = wrapFactory.WrapProduct(func2,log); //使用模板方法,生产并包装小汽车
//将生产与包装分为两个过程,降低耦合度,最大限度提高代码复用率(复用了包装逻辑)
//这样当一个产品的生产程序出问题时,不会干扰其他产品的生产和包装
//需要维护一个产品的生产程序时,也不需要动其他产品的生产和包装程序
//提高维护性、可扩展性
}
}
class Logger //记录程序的运行状态的类,实际开发工程中一般都会有这个类
{
public void Log(Product product) //输出产品状态的方法
{
Console.WriteLine("Produict '{0}' creaded at {1}. Price is {2}.", product.Name, DateTime.UtcNow, product.Price);
}
}
class Product //产品类
{
public string Name { get; set; } //产品成员字段:产品的名字
public double Price { get; set; } //产品的价格
}
class Box //包装箱
{
public Product Product { get; set; } //箱子里包装的产品
}
class WrapFactory //盒子工厂类,用来生产盒子并将产品装入
{
public Box WrapProduct(Func<Product> getProduct,Action<Product> logCallback)
{ //< >中表示作为参数的委托的返回值类型是Product
//模板方法,把产品包上盒子交给用户 回调方法logCallback:显示产品当前状态
Box box = new Box(); //创建一个新盒子
Product product = getProduct.Invoke(); //从委托参数中拿到传进来的产品对象
if(product.Price >= 50) //是否使用回调方法的判断
{
logCallback(product); //若价格大于50元,使用回调方法,输出产品信息
}
box.Product = product; //将产品塞进盒子里
return box; //返回包装好产品的盒子
}
}
class ProductFactory //产品工厂类,用来生产产品,内含多种不同的产品生产方法
{
public Product MakePizza() //用来生产披萨产品
{
Product product = new Product();
product.Name = "Pizza"; //将产品实例的字段填为Pizza
product.Price = 12; //披萨价格12元
return product;
}
public Product MakeToyCar() //用来生产玩具小汽车产品
{
Product product = new Product();
product.Name = "Toy Car"; //将产品实例的字段填为Toy Car
product.Price = 100; //小汽车价格100元
return product;
}
}
}
委托的高级使用
1.多播委托
首先添加一个与多线程相关的命名空间的引用
然后声明一个类,有两个属性
3名学生分别用不同颜色的笔写作业,通过委托简介调用方法
结果:3位学生依次完成了作业
合并委托
将action2和action3都合并进action1,现在action1内就封装了3个方法
然后执行,得到的结果与之前一样
这样一个委托封装多个方法的使用方法叫多播委托
委托中方法的执行顺序按照其封装进方法的先后顺序,先被丢进委托的先执行
2.隐式异步调用EX
同义名词解释
串行 = 同步 = 单线程, 并行 = 异步 = 多线程
1.进程与线程
两项工作同时进行
每一个程序都是一个进程(process)
每一个进程可以有多个线程(thread)
2.同步调用
单线程调用方法,是前一个方法执行完毕,后一个方法才能开始执行
结果是按顺序依次执行,最后执行主线程
3.异步调用
同时执行,各方法线程互不相干,一个方法的开始和结束不会影响另一个线程的开始和结束
4.使用委托的隐式异步调用
使用委托的BeginInvoke方法
两个参数:第一个是异步调用的回调(callback)
结果:主线程与3个分支线程并行执行
第三行和第四行颜色相同原因:
各线程都在调用控制台的前景色这个属性,当多个线程异步访问同一个资源时,可能会因为争抢资源发生冲突,产生这样的错误情况
需要线程加锁等方法避免多线程程序中的资源冲突(待续)
5.显式异步调用
(1)Thread(一种古老方式)
也是各线程独立执行,也发生来了资源争抢
(2)Task
需要引用这个子命名空间
也是各自独立运行,也有资源争抢
编程常识:
JAVA没有委托,完全用接口,但也活地好好的
浙公网安备 33010602011771号